… | |
… | |
336 | #define FUBd \ |
336 | #define FUBd \ |
337 | free (eio_buf) |
337 | free (eio_buf) |
338 | |
338 | |
339 | /*****************************************************************************/ |
339 | /*****************************************************************************/ |
340 | |
340 | |
341 | struct tmpbuf |
|
|
342 | { |
|
|
343 | void *ptr; |
|
|
344 | int len; |
|
|
345 | }; |
|
|
346 | |
|
|
347 | static void * |
|
|
348 | tmpbuf_get (struct tmpbuf *buf, int len) |
|
|
349 | { |
|
|
350 | if (buf->len < len) |
|
|
351 | { |
|
|
352 | free (buf->ptr); |
|
|
353 | buf->ptr = malloc (buf->len = len); |
|
|
354 | } |
|
|
355 | |
|
|
356 | return buf->ptr; |
|
|
357 | } |
|
|
358 | |
|
|
359 | struct tmpbuf; |
341 | struct etp_tmpbuf; |
360 | |
342 | |
361 | #if _POSIX_VERSION >= 200809L |
343 | #if _POSIX_VERSION >= 200809L |
362 | #define HAVE_AT 1 |
344 | #define HAVE_AT 1 |
363 | #define WD2FD(wd) ((wd) ? (wd)->fd : AT_FDCWD) |
345 | #define WD2FD(wd) ((wd) ? (wd)->fd : AT_FDCWD) |
364 | #ifndef O_SEARCH |
346 | #ifndef O_SEARCH |
365 | #define O_SEARCH O_RDONLY |
347 | #define O_SEARCH O_RDONLY |
366 | #endif |
348 | #endif |
367 | #else |
349 | #else |
368 | #define HAVE_AT 0 |
350 | #define HAVE_AT 0 |
369 | static const char *wd_expand (struct tmpbuf *tmpbuf, eio_wd wd, const char *path); |
351 | static const char *wd_expand (struct etp_tmpbuf *tmpbuf, eio_wd wd, const char *path); |
370 | #endif |
352 | #endif |
371 | |
353 | |
372 | struct eio_pwd |
354 | struct eio_pwd |
373 | { |
355 | { |
374 | #if HAVE_AT |
356 | #if HAVE_AT |
… | |
… | |
967 | req->result = req->offs == (off_t)-1 ? -1 : 0; |
949 | req->result = req->offs == (off_t)-1 ? -1 : 0; |
968 | } |
950 | } |
969 | |
951 | |
970 | /* result will always end up in tmpbuf, there is always space for adding a 0-byte */ |
952 | /* result will always end up in tmpbuf, there is always space for adding a 0-byte */ |
971 | static int |
953 | static int |
972 | eio__realpath (struct tmpbuf *tmpbuf, eio_wd wd, const char *path) |
954 | eio__realpath (struct etp_tmpbuf *tmpbuf, eio_wd wd, const char *path) |
973 | { |
955 | { |
974 | char *res; |
956 | char *res; |
975 | const char *rel = path; |
957 | const char *rel = path; |
976 | char *tmp1, *tmp2; |
958 | char *tmp1, *tmp2; |
977 | #if SYMLOOP_MAX > 32 |
959 | #if SYMLOOP_MAX > 32 |
… | |
… | |
986 | |
968 | |
987 | errno = ENOENT; |
969 | errno = ENOENT; |
988 | if (!*rel) |
970 | if (!*rel) |
989 | return -1; |
971 | return -1; |
990 | |
972 | |
991 | res = tmpbuf_get (tmpbuf, PATH_MAX * 3); |
973 | res = etp_tmpbuf_get (tmpbuf, PATH_MAX * 3); |
992 | #ifdef _WIN32 |
974 | #ifdef _WIN32 |
993 | if (_access (rel, 4) != 0) |
975 | if (_access (rel, 4) != 0) |
994 | return -1; |
976 | return -1; |
995 | |
977 | |
996 | symlinks = GetFullPathName (rel, PATH_MAX * 3, res, 0); |
978 | symlinks = GetFullPathName (rel, PATH_MAX * 3, res, 0); |
… | |
… | |
1605 | #if !HAVE_AT |
1587 | #if !HAVE_AT |
1606 | |
1588 | |
1607 | /* a bit like realpath, but usually faster because it doesn'T have to return */ |
1589 | /* a bit like realpath, but usually faster because it doesn'T have to return */ |
1608 | /* an absolute or canonical path */ |
1590 | /* an absolute or canonical path */ |
1609 | static const char * |
1591 | static const char * |
1610 | wd_expand (struct tmpbuf *tmpbuf, eio_wd wd, const char *path) |
1592 | wd_expand (struct etp_tmpbuf *tmpbuf, eio_wd wd, const char *path) |
1611 | { |
1593 | { |
1612 | if (!wd || *path == '/') |
1594 | if (!wd || *path == '/') |
1613 | return path; |
1595 | return path; |
1614 | |
1596 | |
1615 | if (path [0] == '.' && !path [1]) |
1597 | if (path [0] == '.' && !path [1]) |
… | |
… | |
1617 | |
1599 | |
1618 | { |
1600 | { |
1619 | int l1 = wd->len; |
1601 | int l1 = wd->len; |
1620 | int l2 = strlen (path); |
1602 | int l2 = strlen (path); |
1621 | |
1603 | |
1622 | char *res = tmpbuf_get (tmpbuf, l1 + l2 + 2); |
1604 | char *res = etp_tmpbuf_get (tmpbuf, l1 + l2 + 2); |
1623 | |
1605 | |
1624 | memcpy (res, wd->str, l1); |
1606 | memcpy (res, wd->str, l1); |
1625 | res [l1] = '/'; |
1607 | res [l1] = '/'; |
1626 | memcpy (res + l1 + 1, path, l2 + 1); |
1608 | memcpy (res + l1 + 1, path, l2 + 1); |
1627 | |
1609 | |
… | |
… | |
1630 | } |
1612 | } |
1631 | |
1613 | |
1632 | #endif |
1614 | #endif |
1633 | |
1615 | |
1634 | static eio_wd |
1616 | static eio_wd |
1635 | eio__wd_open_sync (struct tmpbuf *tmpbuf, eio_wd wd, const char *path) |
1617 | eio__wd_open_sync (struct etp_tmpbuf *tmpbuf, eio_wd wd, const char *path) |
1636 | { |
1618 | { |
1637 | int fd; |
1619 | int fd; |
1638 | eio_wd res; |
1620 | eio_wd res; |
1639 | int len = eio__realpath (tmpbuf, wd, path); |
1621 | int len = eio__realpath (tmpbuf, wd, path); |
1640 | |
1622 | |
… | |
… | |
1662 | } |
1644 | } |
1663 | |
1645 | |
1664 | eio_wd |
1646 | eio_wd |
1665 | eio_wd_open_sync (eio_wd wd, const char *path) |
1647 | eio_wd_open_sync (eio_wd wd, const char *path) |
1666 | { |
1648 | { |
1667 | struct tmpbuf tmpbuf = { 0 }; |
1649 | struct etp_tmpbuf tmpbuf = { }; |
1668 | wd = eio__wd_open_sync (&tmpbuf, wd, path); |
1650 | wd = eio__wd_open_sync (&tmpbuf, wd, path); |
1669 | free (tmpbuf.ptr); |
1651 | free (tmpbuf.ptr); |
1670 | |
1652 | |
1671 | return wd; |
1653 | return wd; |
1672 | } |
1654 | } |