diff options
author | Enji Cooper <ngie@FreeBSD.org> | 2017-08-04 17:41:49 +0000 |
---|---|---|
committer | Enji Cooper <ngie@FreeBSD.org> | 2017-08-04 17:41:49 +0000 |
commit | da48ebc4de409fe039826d36b1da1f78ff5f84fc (patch) | |
tree | 58e2ac3c336e4a06eba7123cc97c0c89fb6671c1 | |
parent | de6f37f33940a64b85b2af2d427295b55a93e2e1 (diff) | |
parent | 6dc9032c654984992ef940fc975e99066897442d (diff) | |
download | pw-darwin-da48ebc4de409fe039826d36b1da1f78ff5f84fc.tar.gz pw-darwin-da48ebc4de409fe039826d36b1da1f78ff5f84fc.tar.zst pw-darwin-da48ebc4de409fe039826d36b1da1f78ff5f84fc.zip |
MFhead@r322057
-rw-r--r-- | libutil/flopen.c | 36 | ||||
-rw-r--r-- | libutil/libutil.h | 1 |
2 files changed, 29 insertions, 8 deletions
diff --git a/libutil/flopen.c b/libutil/flopen.c index 8929729..bb5d996 100644 --- a/libutil/flopen.c +++ b/libutil/flopen.c @@ -45,8 +45,8 @@ __FBSDID("$FreeBSD$"); * code's apparent simplicity; there would be no need for this function if it * was easy to get right. */ -int -flopen(const char *path, int flags, ...) +static int +vflopenat(int dirfd, const char *path, int flags, va_list ap) { int fd, operation, serrno, trunc; struct stat sb, fsb; @@ -58,11 +58,7 @@ flopen(const char *path, int flags, ...) mode = 0; if (flags & O_CREAT) { - va_list ap; - - va_start(ap, flags); mode = (mode_t)va_arg(ap, int); /* mode_t promoted to int */ - va_end(ap); } operation = LOCK_EX; @@ -73,7 +69,7 @@ flopen(const char *path, int flags, ...) flags &= ~O_TRUNC; for (;;) { - if ((fd = open(path, flags, mode)) == -1) + if ((fd = openat(dirfd, path, flags, mode)) == -1) /* non-existent or no access */ return (-1); if (flock(fd, operation) == -1) { @@ -83,7 +79,7 @@ flopen(const char *path, int flags, ...) errno = serrno; return (-1); } - if (stat(path, &sb) == -1) { + if (fstatat(dirfd, path, &sb, 0) == -1) { /* disappeared from under our feet */ (void)close(fd); continue; @@ -123,3 +119,27 @@ flopen(const char *path, int flags, ...) return (fd); } } + +int +flopen(const char *path, int flags, ...) +{ + va_list ap; + int ret; + + va_start(ap, flags); + ret = vflopenat(AT_FDCWD, path, flags, ap); + va_end(ap); + return (ret); +} + +int +flopenat(int dirfd, const char *path, int flags, ...) +{ + va_list ap; + int ret; + + va_start(ap, flags); + ret = vflopenat(dirfd, path, flags, ap); + va_end(ap); + return (ret); +} diff --git a/libutil/libutil.h b/libutil/libutil.h index b20ffa2..fa924db 100644 --- a/libutil/libutil.h +++ b/libutil/libutil.h @@ -93,6 +93,7 @@ int expand_number(const char *_buf, uint64_t *_num); int extattr_namespace_to_string(int _attrnamespace, char **_string); int extattr_string_to_namespace(const char *_string, int *_attrnamespace); int flopen(const char *_path, int _flags, ...); +int flopenat(int _dirfd, const char *_path, int _flags, ...); int forkpty(int *_amaster, char *_name, struct termios *_termp, struct winsize *_winp); void hexdump(const void *_ptr, int _length, const char *_hdr, int _flags); |