summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarren Tucker <dtucker@dtucker.net>2019-01-18 11:09:01 +1100
committerDarren Tucker <dtucker@dtucker.net>2019-01-18 11:09:01 +1100
commita6258e5dc314c7d504ac9f0fbc3be96475581dbe (patch)
tree19047ce95b4608e7791ef419452c000055a6dac7
parent091093d25802b87d3b2b09f2c88d9f33e1ae5562 (diff)
Add minimal fchownat and fchmodat implementations.
Fixes builds on at least OS X Lion, NetBSD 6 and Solaris 10.
-rw-r--r--configure.ac2
-rw-r--r--openbsd-compat/bsd-misc.c58
-rw-r--r--openbsd-compat/bsd-misc.h12
3 files changed, 72 insertions, 0 deletions
diff --git a/configure.ac b/configure.ac
index 2d1dafdee..8e92d1599 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1719,7 +1719,9 @@ AC_CHECK_FUNCS([ \
1719 errx \ 1719 errx \
1720 explicit_bzero \ 1720 explicit_bzero \
1721 fchmod \ 1721 fchmod \
1722 fchmodat \
1722 fchown \ 1723 fchown \
1724 fchownat \
1723 flock \ 1725 flock \
1724 freeaddrinfo \ 1726 freeaddrinfo \
1725 freezero \ 1727 freezero \
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],
154} 154}
155#endif 155#endif
156 156
157#ifndef HAVE_FCHOWNAT
158/*
159 * A limited implementation of fchownat() that only implements the
160 * functionality used by OpenSSH, currently only AT_FDCWD and
161 * AT_SYMLINK_NOFOLLOW.
162 */
163int
164fchownat(int fd, const char *path, uid_t owner, gid_t group, int flag)
165{
166 int ret, oflags = O_WRONLY;
167
168 if (fd != AT_FDCWD) {
169 errno = ENOSYS;
170 return -1;
171 }
172# ifndef HAVE_FCHOWN
173 return chown(pathname, owner, group);
174# else
175 if (flag & AT_SYMLINK_NOFOLLOW)
176 oflags |= O_NOFOLLOW;
177 if ((fd = open(path, oflags)) == -1)
178 return -1;
179 ret = fchown(fd, owner, group);
180 close(fd);
181 return ret;
182# endif
183}
184#endif
185
186#ifndef HAVE_FCHMODAT
187/*
188 * A limited implementation of fchmodat() that only implements the
189 * functionality used by OpenSSH, currently only AT_FDCWD and
190 * AT_SYMLINK_NOFOLLOW.
191 */
192int
193fchmodat(int fd, const char *path, mode_t mode, int flag)
194{
195 int ret, oflags = O_WRONLY;
196
197 if (fd != AT_FDCWD) {
198 errno = ENOSYS;
199 return -1;
200 }
201# ifndef HAVE_FCHMOD
202 return chown(pathname, owner, group);
203# else
204 if (flag & AT_SYMLINK_NOFOLLOW)
205 oflags |= O_NOFOLLOW;
206 if ((fd = open(path, oflags)) == -1)
207 return -1;
208 ret = fchmod(fd, mode);
209 close(fd);
210 return ret;
211# endif
212}
213#endif
214
157#ifndef HAVE_TRUNCATE 215#ifndef HAVE_TRUNCATE
158int truncate(const char *path, off_t length) 216int truncate(const char *path, off_t length)
159{ 217{
diff --git a/openbsd-compat/bsd-misc.h b/openbsd-compat/bsd-misc.h
index 584c2b5ef..cb158cd5c 100644
--- a/openbsd-compat/bsd-misc.h
+++ b/openbsd-compat/bsd-misc.h
@@ -72,6 +72,18 @@ int utimes(char *, struct timeval *);
72int utimensat(int, const char *, const struct timespec[2], int); 72int utimensat(int, const char *, const struct timespec[2], int);
73#endif 73#endif
74 74
75#ifndef AT_FDCWD
76# define AT_FDCWD (-2)
77#endif
78
79#ifndef HAVE_FCHMODAT
80int fchmodat(int, const char *, mode_t, int);
81#endif
82
83#ifndef HAVE_FCHOWNAT
84int fchownat(int, const char *, uid_t, gid_t, int);
85#endif
86
75#ifndef HAVE_TRUNCATE 87#ifndef HAVE_TRUNCATE
76int truncate (const char *, off_t); 88int truncate (const char *, off_t);
77#endif /* HAVE_TRUNCATE */ 89#endif /* HAVE_TRUNCATE */