1 | /* |
1 | /* |
2 | * libeio implementation |
2 | * libeio implementation |
3 | * |
3 | * |
4 | * Copyright (c) 2007,2008,2009,2010,2011,2012,2013,2016,2017 Marc Alexander Lehmann <libeio@schmorp.de> |
4 | * Copyright (c) 2007,2008,2009,2010,2011,2012,2013,2016,2017,2018 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 | * |
… | |
… | |
329 | |
329 | |
330 | #ifndef O_CLOEXEC |
330 | #ifndef O_CLOEXEC |
331 | #define O_CLOEXEC 0 |
331 | #define O_CLOEXEC 0 |
332 | #endif |
332 | #endif |
333 | |
333 | |
|
|
334 | #ifndef O_NONBLOCK |
|
|
335 | #define O_NONBLOCK 0 |
|
|
336 | #endif |
|
|
337 | |
|
|
338 | #ifndef O_SEARCH |
|
|
339 | #define O_SEARCH O_RDONLY |
|
|
340 | #endif |
|
|
341 | |
|
|
342 | #ifndef O_DIRECTORY |
|
|
343 | #define O_DIRECTORY 0 |
|
|
344 | #endif |
|
|
345 | |
334 | #ifndef EIO_PATH_MIN |
346 | #ifndef EIO_PATH_MIN |
335 | # define EIO_PATH_MIN 8160 |
347 | # define EIO_PATH_MIN 8160 |
336 | #endif |
348 | #endif |
337 | |
349 | |
338 | #define EIO_PATH_MAX (PATH_MAX <= EIO_PATH_MIN ? EIO_PATH_MIN : PATH_MAX) |
350 | #define EIO_PATH_MAX (PATH_MAX <= EIO_PATH_MIN ? EIO_PATH_MIN : PATH_MAX) |
… | |
… | |
354 | struct etp_tmpbuf; |
366 | struct etp_tmpbuf; |
355 | |
367 | |
356 | #if _POSIX_VERSION >= 200809L |
368 | #if _POSIX_VERSION >= 200809L |
357 | #define HAVE_AT 1 |
369 | #define HAVE_AT 1 |
358 | #define WD2FD(wd) ((wd) ? (wd)->fd : AT_FDCWD) |
370 | #define WD2FD(wd) ((wd) ? (wd)->fd : AT_FDCWD) |
359 | #ifndef O_SEARCH |
|
|
360 | #define O_SEARCH O_RDONLY |
|
|
361 | #endif |
|
|
362 | #else |
371 | #else |
363 | #define HAVE_AT 0 |
372 | #define HAVE_AT 0 |
364 | static const char *wd_expand (struct etp_tmpbuf *tmpbuf, eio_wd wd, const char *path); |
373 | static const char *wd_expand (struct etp_tmpbuf *tmpbuf, eio_wd wd, const char *path); |
365 | #endif |
374 | #endif |
366 | |
375 | |
… | |
… | |
893 | #if __GLIBC__ == 2 && __GLIBC_MINOR__ <= 7 |
902 | #if __GLIBC__ == 2 && __GLIBC_MINOR__ <= 7 |
894 | extern int mallopt (int, int); |
903 | extern int mallopt (int, int); |
895 | mallopt (-6, 238); /* http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=473812 */ |
904 | mallopt (-6, 238); /* http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=473812 */ |
896 | #endif |
905 | #endif |
897 | |
906 | |
|
|
907 | #ifndef MCL_ONFAULT |
|
|
908 | if (flags & EIO_MCL_ONFAULT) |
|
|
909 | return EIO_ERRNO (EINVAL, -1); |
|
|
910 | #define MCL_ONFAULT 4 |
|
|
911 | #endif |
|
|
912 | |
898 | if (EIO_MCL_CURRENT != MCL_CURRENT |
913 | if (EIO_MCL_CURRENT != MCL_CURRENT |
899 | || EIO_MCL_FUTURE != MCL_FUTURE) |
914 | || EIO_MCL_FUTURE != MCL_FUTURE |
|
|
915 | || EIO_MCL_ONFAULT != MCL_ONFAULT) |
900 | { |
916 | { |
901 | flags = 0 |
917 | flags = 0 |
902 | | (flags & EIO_MCL_CURRENT ? MCL_CURRENT : 0) |
918 | | (flags & EIO_MCL_CURRENT ? MCL_CURRENT : 0) |
903 | | (flags & EIO_MCL_FUTURE ? MCL_FUTURE : 0); |
919 | | (flags & EIO_MCL_FUTURE ? MCL_FUTURE : 0) |
|
|
920 | | (flags & EIO_MCL_ONFAULT ? MCL_ONFAULT : 0) |
|
|
921 | ; |
904 | } |
922 | } |
905 | |
923 | |
906 | return mlockall (flags); |
924 | return mlockall (flags); |
907 | } |
925 | } |
908 | #endif |
926 | #endif |
… | |
… | |
1395 | return; |
1413 | return; |
1396 | } |
1414 | } |
1397 | } |
1415 | } |
1398 | #else |
1416 | #else |
1399 | #if HAVE_AT |
1417 | #if HAVE_AT |
1400 | if (req->wd) |
|
|
1401 | { |
1418 | { |
1402 | int fd = openat (WD2FD (req->wd), req->ptr1, O_CLOEXEC | O_SEARCH | O_DIRECTORY); |
1419 | int fd = openat (WD2FD (req->wd), req->ptr1, O_CLOEXEC | O_SEARCH | O_DIRECTORY | O_NONBLOCK); |
1403 | |
1420 | |
1404 | if (fd < 0) |
1421 | if (fd < 0) |
|
|
1422 | return; |
|
|
1423 | |
|
|
1424 | dirp = fdopendir (fd); |
|
|
1425 | |
|
|
1426 | if (!dirp) |
|
|
1427 | { |
|
|
1428 | silent_close (fd); |
1405 | return; |
1429 | return; |
1406 | |
|
|
1407 | dirp = fdopendir (fd); |
|
|
1408 | |
|
|
1409 | if (!dirp) |
|
|
1410 | silent_close (fd); |
|
|
1411 | } |
1430 | } |
1412 | else |
1431 | } |
1413 | dirp = opendir (req->ptr1); |
|
|
1414 | #else |
1432 | #else |
1415 | dirp = opendir (wd_expand (&self->tmpbuf, req->wd, req->ptr1)); |
1433 | dirp = opendir (wd_expand (&self->tmpbuf, req->wd, req->ptr1)); |
|
|
1434 | |
|
|
1435 | if (!dirp) |
|
|
1436 | return; |
1416 | #endif |
1437 | #endif |
1417 | |
|
|
1418 | if (!dirp) |
|
|
1419 | return; |
|
|
1420 | #endif |
1438 | #endif |
1421 | |
1439 | |
1422 | if (req->flags & EIO_FLAG_PTR1_FREE) |
1440 | if (req->flags & EIO_FLAG_PTR1_FREE) |
1423 | free (req->ptr1); |
1441 | free (req->ptr1); |
1424 | |
1442 | |
… | |
… | |
1659 | |
1677 | |
1660 | if (len < 0) |
1678 | if (len < 0) |
1661 | return EIO_INVALID_WD; |
1679 | return EIO_INVALID_WD; |
1662 | |
1680 | |
1663 | #if HAVE_AT |
1681 | #if HAVE_AT |
1664 | fd = openat (WD2FD (wd), path, O_CLOEXEC | O_SEARCH | O_DIRECTORY); |
1682 | fd = openat (WD2FD (wd), path, O_CLOEXEC | O_SEARCH | O_DIRECTORY | O_NONBLOCK); |
1665 | |
1683 | |
1666 | if (fd < 0) |
1684 | if (fd < 0) |
1667 | return EIO_INVALID_WD; |
1685 | return EIO_INVALID_WD; |
1668 | #endif |
1686 | #endif |
1669 | |
1687 | |
… | |
… | |
1681 | } |
1699 | } |
1682 | |
1700 | |
1683 | eio_wd |
1701 | eio_wd |
1684 | eio_wd_open_sync (eio_wd wd, const char *path) |
1702 | eio_wd_open_sync (eio_wd wd, const char *path) |
1685 | { |
1703 | { |
1686 | struct etp_tmpbuf tmpbuf = { }; |
1704 | struct etp_tmpbuf tmpbuf = { 0 }; |
1687 | wd = eio__wd_open_sync (&tmpbuf, wd, path); |
1705 | wd = eio__wd_open_sync (&tmpbuf, wd, path); |
1688 | free (tmpbuf.ptr); |
1706 | free (tmpbuf.ptr); |
1689 | |
1707 | |
1690 | return wd; |
1708 | return wd; |
1691 | } |
1709 | } |
… | |
… | |
1720 | /* they forgot these */ |
1738 | /* they forgot these */ |
1721 | |
1739 | |
1722 | static int |
1740 | static int |
1723 | eio__truncateat (int dirfd, const char *path, off_t length) |
1741 | eio__truncateat (int dirfd, const char *path, off_t length) |
1724 | { |
1742 | { |
1725 | int fd = openat (dirfd, path, O_WRONLY | O_CLOEXEC); |
1743 | int fd = openat (dirfd, path, O_WRONLY | O_CLOEXEC | O_NONBLOCK); |
1726 | int res; |
1744 | int res; |
1727 | |
1745 | |
1728 | if (fd < 0) |
1746 | if (fd < 0) |
1729 | return fd; |
1747 | return fd; |
1730 | |
1748 | |
… | |
… | |
1734 | } |
1752 | } |
1735 | |
1753 | |
1736 | static int |
1754 | static int |
1737 | eio__statvfsat (int dirfd, const char *path, struct statvfs *buf) |
1755 | eio__statvfsat (int dirfd, const char *path, struct statvfs *buf) |
1738 | { |
1756 | { |
1739 | int fd = openat (dirfd, path, O_SEARCH | O_CLOEXEC); |
1757 | int fd = openat (dirfd, path, O_SEARCH | O_CLOEXEC | O_NONBLOCK); |
1740 | int res; |
1758 | int res; |
1741 | |
1759 | |
1742 | if (fd < 0) |
1760 | if (fd < 0) |
1743 | return fd; |
1761 | return fd; |
1744 | |
1762 | |
… | |
… | |
2409 | eio_sendfile_sync (int ofd, int ifd, off_t offset, size_t count) |
2427 | eio_sendfile_sync (int ofd, int ifd, off_t offset, size_t count) |
2410 | { |
2428 | { |
2411 | return eio__sendfile (ofd, ifd, offset, count); |
2429 | return eio__sendfile (ofd, ifd, offset, count); |
2412 | } |
2430 | } |
2413 | |
2431 | |
|
|
2432 | int eio_mlockall_sync (int flags) |
|
|
2433 | { |
|
|
2434 | return eio__mlockall (flags); |
|
|
2435 | } |
|
|
2436 | |