diff options
author | Darren Tucker <dtucker@dtucker.net> | 2019-01-18 01:09:01 +0100 |
---|---|---|
committer | Darren Tucker <dtucker@dtucker.net> | 2019-01-18 01:09:01 +0100 |
commit | a6258e5dc314c7d504ac9f0fbc3be96475581dbe (patch) | |
tree | 19047ce95b4608e7791ef419452c000055a6dac7 /openbsd-compat/bsd-misc.c | |
parent | Add a minimal implementation of utimensat(). (diff) | |
download | openssh-a6258e5dc314c7d504ac9f0fbc3be96475581dbe.tar.xz openssh-a6258e5dc314c7d504ac9f0fbc3be96475581dbe.zip |
Add minimal fchownat and fchmodat implementations.
Fixes builds on at least OS X Lion, NetBSD 6 and Solaris 10.
Diffstat (limited to 'openbsd-compat/bsd-misc.c')
-rw-r--r-- | openbsd-compat/bsd-misc.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/openbsd-compat/bsd-misc.c b/openbsd-compat/bsd-misc.c index 4bae96548..d3a41df50 100644 --- a/openbsd-compat/bsd-misc.c +++ b/openbsd-compat/bsd-misc.c @@ -154,6 +154,64 @@ utimensat(int fd, const char *path, const struct timespec times[2], } #endif +#ifndef HAVE_FCHOWNAT +/* + * A limited implementation of fchownat() that only implements the + * functionality used by OpenSSH, currently only AT_FDCWD and + * AT_SYMLINK_NOFOLLOW. + */ +int +fchownat(int fd, const char *path, uid_t owner, gid_t group, int flag) +{ + int ret, oflags = O_WRONLY; + + if (fd != AT_FDCWD) { + errno = ENOSYS; + return -1; + } +# ifndef HAVE_FCHOWN + return chown(pathname, owner, group); +# else + if (flag & AT_SYMLINK_NOFOLLOW) + oflags |= O_NOFOLLOW; + if ((fd = open(path, oflags)) == -1) + return -1; + ret = fchown(fd, owner, group); + close(fd); + return ret; +# endif +} +#endif + +#ifndef HAVE_FCHMODAT +/* + * A limited implementation of fchmodat() that only implements the + * functionality used by OpenSSH, currently only AT_FDCWD and + * AT_SYMLINK_NOFOLLOW. + */ +int +fchmodat(int fd, const char *path, mode_t mode, int flag) +{ + int ret, oflags = O_WRONLY; + + if (fd != AT_FDCWD) { + errno = ENOSYS; + return -1; + } +# ifndef HAVE_FCHMOD + return chown(pathname, owner, group); +# else + if (flag & AT_SYMLINK_NOFOLLOW) + oflags |= O_NOFOLLOW; + if ((fd = open(path, oflags)) == -1) + return -1; + ret = fchmod(fd, mode); + close(fd); + return ret; +# endif +} +#endif + #ifndef HAVE_TRUNCATE int truncate(const char *path, off_t length) { |