… | |
… | |
4 | * Copyright (c) 2007,2008,2009,2010,2011,2012 Marc Alexander Lehmann <libeio@schmorp.de> |
4 | * Copyright (c) 2007,2008,2009,2010,2011,2012 Marc Alexander Lehmann <libeio@schmorp.de> |
5 | * All rights reserved. |
5 | * All rights reserved. |
6 | * |
6 | * |
7 | * Redistribution and use in source and binary forms, with or without modifica- |
7 | * Redistribution and use in source and binary forms, with or without modifica- |
8 | * tion, are permitted provided that the following conditions are met: |
8 | * tion, are permitted provided that the following conditions are met: |
9 | * |
9 | * |
10 | * 1. Redistributions of source code must retain the above copyright notice, |
10 | * 1. Redistributions of source code must retain the above copyright notice, |
11 | * this list of conditions and the following disclaimer. |
11 | * this list of conditions and the following disclaimer. |
12 | * |
12 | * |
13 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * 2. Redistributions in binary form must reproduce the above copyright |
14 | * notice, this list of conditions and the following disclaimer in the |
14 | * notice, this list of conditions and the following disclaimer in the |
15 | * documentation and/or other materials provided with the distribution. |
15 | * documentation and/or other materials provided with the distribution. |
16 | * |
16 | * |
17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED |
17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED |
18 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- |
18 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- |
19 | * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO |
19 | * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO |
20 | * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- |
20 | * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- |
21 | * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
21 | * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
… | |
… | |
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 | |
… | |
… | |
602 | /*TODO*/ |
602 | /*TODO*/ |
603 | assert (("unable to allocate worker thread data", wrk)); |
603 | assert (("unable to allocate worker thread data", wrk)); |
604 | |
604 | |
605 | X_LOCK (wrklock); |
605 | X_LOCK (wrklock); |
606 | |
606 | |
607 | if (thread_create (&wrk->tid, etp_proc, (void *)wrk)) |
607 | if (xthread_create (&wrk->tid, etp_proc, (void *)wrk)) |
608 | { |
608 | { |
609 | wrk->prev = &wrk_first; |
609 | wrk->prev = &wrk_first; |
610 | wrk->next = wrk_first.next; |
610 | wrk->next = wrk_first.next; |
611 | wrk_first.next->prev = wrk; |
611 | wrk_first.next->prev = wrk; |
612 | wrk_first.next = wrk; |
612 | wrk_first.next = wrk; |
… | |
… | |
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; |