… | |
… | |
316 | #endif |
316 | #endif |
317 | |
317 | |
318 | /* buffer size for various temporary buffers */ |
318 | /* buffer size for various temporary buffers */ |
319 | #define EIO_BUFSIZE 65536 |
319 | #define EIO_BUFSIZE 65536 |
320 | |
320 | |
321 | #define dBUF \ |
321 | #define dBUF \ |
322 | char *eio_buf = malloc (EIO_BUFSIZE); \ |
322 | char *eio_buf = malloc (EIO_BUFSIZE); \ |
323 | errno = ENOMEM; \ |
323 | errno = ENOMEM; \ |
324 | if (!eio_buf) \ |
324 | if (!eio_buf) \ |
325 | return -1 |
325 | return -1 |
326 | |
326 | |
… | |
… | |
1416 | |
1416 | |
1417 | if (fd >= 0) |
1417 | if (fd >= 0) |
1418 | { |
1418 | { |
1419 | sprintf (tmp1, "/proc/self/fd/%d", fd); |
1419 | sprintf (tmp1, "/proc/self/fd/%d", fd); |
1420 | req->result = readlink (tmp1, res, PATH_MAX); |
1420 | req->result = readlink (tmp1, res, PATH_MAX); |
|
|
1421 | /* here we should probably stat the open file and the disk file, to make sure they still match */ |
1421 | close (fd); |
1422 | close (fd); |
1422 | |
|
|
1423 | /* here we should probably stat the open file and the disk file, to make sure they still match */ |
|
|
1424 | |
1423 | |
1425 | if (req->result > 0) |
1424 | if (req->result > 0) |
1426 | goto done; |
1425 | goto done; |
1427 | } |
1426 | } |
1428 | else if (errno == ELOOP || errno == ENAMETOOLONG || errno == ENOENT || errno == ENOTDIR || errno == EIO) |
1427 | else if (errno == ELOOP || errno == ENAMETOOLONG || errno == ENOENT || errno == ENOTDIR || errno == EIO) |
1429 | return; |
1428 | return -1; |
1430 | } |
1429 | } |
1431 | #endif |
1430 | #endif |
1432 | #endif |
1431 | #endif |
1433 | |
1432 | |
1434 | if (*rel != '/') |
1433 | if (*rel != '/') |
… | |
… | |
2269 | { \ |
2268 | { \ |
2270 | eio_api_destroy (req); \ |
2269 | eio_api_destroy (req); \ |
2271 | return 0; \ |
2270 | return 0; \ |
2272 | } |
2271 | } |
2273 | |
2272 | |
|
|
2273 | #define SINGLEDOT(ptr) (0[(char *)(ptr)] == '.' && !1[(char *)(ptr)]) |
|
|
2274 | |
2274 | static void |
2275 | static void |
2275 | eio_execute (etp_worker *self, eio_req *req) |
2276 | eio_execute (etp_worker *self, eio_req *req) |
2276 | { |
2277 | { |
2277 | #if HAVE_AT |
2278 | #if HAVE_AT |
2278 | int dirfd; |
2279 | int dirfd; |
… | |
… | |
2333 | case EIO_CHMOD: req->result = fchmodat (dirfd, req->ptr1, (mode_t)req->int2, 0); break; |
2334 | case EIO_CHMOD: req->result = fchmodat (dirfd, req->ptr1, (mode_t)req->int2, 0); break; |
2334 | case EIO_TRUNCATE: req->result = eio__truncateat (dirfd, req->ptr1, req->offs); break; |
2335 | case EIO_TRUNCATE: req->result = eio__truncateat (dirfd, req->ptr1, req->offs); break; |
2335 | case EIO_OPEN: req->result = openat (dirfd, req->ptr1, req->int1, (mode_t)req->int2); break; |
2336 | case EIO_OPEN: req->result = openat (dirfd, req->ptr1, req->int1, (mode_t)req->int2); break; |
2336 | |
2337 | |
2337 | case EIO_UNLINK: req->result = unlinkat (dirfd, req->ptr1, 0); break; |
2338 | case EIO_UNLINK: req->result = unlinkat (dirfd, req->ptr1, 0); break; |
2338 | case EIO_RMDIR: req->result = unlinkat (dirfd, req->ptr1, AT_REMOVEDIR); break; |
2339 | case EIO_RMDIR: /* complications arise because "." cannot be removed, so we might have to expand */ |
|
|
2340 | req->result = req->wd && SINGLEDOT (req->ptr1) |
|
|
2341 | ? rmdir (req->wd->str) |
|
|
2342 | : unlinkat (dirfd, req->ptr1, AT_REMOVEDIR); break; |
2339 | case EIO_MKDIR: req->result = mkdirat (dirfd, req->ptr1, (mode_t)req->int2); break; |
2343 | case EIO_MKDIR: req->result = mkdirat (dirfd, req->ptr1, (mode_t)req->int2); break; |
2340 | case EIO_RENAME: req->result = renameat (dirfd, req->ptr1, WD2FD ((eio_wd)req->int3), req->ptr2); break; |
2344 | case EIO_RENAME: /* complications arise because "." cannot be renamed, so we might have to expand */ |
|
|
2345 | req->result = req->wd && SINGLEDOT (req->ptr1) |
|
|
2346 | ? rename (req->wd->str, req->ptr2) |
|
|
2347 | : renameat (dirfd, req->ptr1, WD2FD ((eio_wd)req->int3), req->ptr2); break; |
2341 | case EIO_LINK: req->result = linkat (dirfd, req->ptr1, WD2FD ((eio_wd)req->int3), req->ptr2, 0); break; |
2348 | case EIO_LINK: req->result = linkat (dirfd, req->ptr1, WD2FD ((eio_wd)req->int3), req->ptr2, 0); break; |
2342 | case EIO_SYMLINK: req->result = symlinkat (req->ptr1, dirfd, req->ptr2); break; |
2349 | case EIO_SYMLINK: req->result = symlinkat (req->ptr1, dirfd, req->ptr2); break; |
2343 | case EIO_MKNOD: req->result = mknodat (dirfd, req->ptr1, (mode_t)req->int2, (dev_t)req->offs); break; |
2350 | case EIO_MKNOD: req->result = mknodat (dirfd, req->ptr1, (mode_t)req->int2, (dev_t)req->offs); break; |
2344 | case EIO_READLINK: ALLOC (PATH_MAX); |
2351 | case EIO_READLINK: ALLOC (PATH_MAX); |
2345 | req->result = readlinkat (dirfd, req->ptr1, req->ptr2, PATH_MAX); break; |
2352 | req->result = readlinkat (dirfd, req->ptr1, req->ptr2, PATH_MAX); break; |