summaryrefslogtreecommitdiff
path: root/openbsd-compat/bsd-misc.c
diff options
context:
space:
mode:
Diffstat (limited to 'openbsd-compat/bsd-misc.c')
-rw-r--r--openbsd-compat/bsd-misc.c101
1 files changed, 101 insertions, 0 deletions
diff --git a/openbsd-compat/bsd-misc.c b/openbsd-compat/bsd-misc.c
index 5d7540a70..aa1c7d7a3 100644
--- a/openbsd-compat/bsd-misc.c
+++ b/openbsd-compat/bsd-misc.c
@@ -25,6 +25,7 @@
25# include <sys/time.h> 25# include <sys/time.h>
26#endif 26#endif
27 27
28#include <fcntl.h>
28#include <string.h> 29#include <string.h>
29#include <signal.h> 30#include <signal.h>
30#include <stdlib.h> 31#include <stdlib.h>
@@ -117,6 +118,106 @@ int utimes(char *filename, struct timeval *tvp)
117} 118}
118#endif 119#endif
119 120
121#ifndef HAVE_UTIMENSAT
122/*
123 * A limited implementation of utimensat() that only implements the
124 * functionality used by OpenSSH, currently only AT_FDCWD and
125 * AT_SYMLINK_NOFOLLOW.
126 */
127int
128utimensat(int fd, const char *path, const struct timespec times[2],
129 int flag)
130{
131 struct timeval tv[2];
132 int ret, oflags = O_WRONLY;
133
134 tv[0].tv_sec = times[0].tv_sec;
135 tv[0].tv_usec = times[0].tv_nsec / 1000;
136 tv[1].tv_sec = times[1].tv_sec;
137 tv[1].tv_usec = times[1].tv_nsec / 1000;
138
139 if (fd != AT_FDCWD) {
140 errno = ENOSYS;
141 return -1;
142 }
143# ifndef HAVE_FUTIMES
144 return utimes(path, tv);
145# else
146# ifdef O_NOFOLLOW
147 if (flag & AT_SYMLINK_NOFOLLOW)
148 oflags |= O_NOFOLLOW;
149# endif /* O_NOFOLLOW */
150 if ((fd = open(path, oflags)) == -1)
151 return -1;
152 ret = futimes(fd, tv);
153 close(fd);
154 return ret;
155# endif
156}
157#endif
158
159#ifndef HAVE_FCHOWNAT
160/*
161 * A limited implementation of fchownat() that only implements the
162 * functionality used by OpenSSH, currently only AT_FDCWD and
163 * AT_SYMLINK_NOFOLLOW.
164 */
165int
166fchownat(int fd, const char *path, uid_t owner, gid_t group, int flag)
167{
168 int ret, oflags = O_WRONLY;
169
170 if (fd != AT_FDCWD) {
171 errno = ENOSYS;
172 return -1;
173 }
174# ifndef HAVE_FCHOWN
175 return chown(pathname, owner, group);
176# else
177# ifdef O_NOFOLLOW
178 if (flag & AT_SYMLINK_NOFOLLOW)
179 oflags |= O_NOFOLLOW;
180# endif /* O_NOFOLLOW */
181 if ((fd = open(path, oflags)) == -1)
182 return -1;
183 ret = fchown(fd, owner, group);
184 close(fd);
185 return ret;
186# endif
187}
188#endif
189
190#ifndef HAVE_FCHMODAT
191/*
192 * A limited implementation of fchmodat() that only implements the
193 * functionality used by OpenSSH, currently only AT_FDCWD and
194 * AT_SYMLINK_NOFOLLOW.
195 */
196int
197fchmodat(int fd, const char *path, mode_t mode, int flag)
198{
199 int ret, oflags = O_WRONLY;
200
201 if (fd != AT_FDCWD) {
202 errno = ENOSYS;
203 return -1;
204 }
205# ifndef HAVE_FCHMOD
206 return chown(pathname, owner, group);
207# else
208# ifdef O_NOFOLLOW
209 if (flag & AT_SYMLINK_NOFOLLOW)
210 oflags |= O_NOFOLLOW;
211# endif /* O_NOFOLLOW */
212 if ((fd = open(path, oflags)) == -1)
213 return -1;
214 ret = fchmod(fd, mode);
215 close(fd);
216 return ret;
217# endif
218}
219#endif
220
120#ifndef HAVE_TRUNCATE 221#ifndef HAVE_TRUNCATE
121int truncate(const char *path, off_t length) 222int truncate(const char *path, off_t length)
122{ 223{