diff options
Diffstat (limited to 'crypto/openssh/openbsd-compat/bsd-misc.c')
-rw-r--r-- | crypto/openssh/openbsd-compat/bsd-misc.c | 135 |
1 files changed, 134 insertions, 1 deletions
diff --git a/crypto/openssh/openbsd-compat/bsd-misc.c b/crypto/openssh/openbsd-compat/bsd-misc.c index 5d7540a70f4b..226a5915bd1d 100644 --- a/crypto/openssh/openbsd-compat/bsd-misc.c +++ b/crypto/openssh/openbsd-compat/bsd-misc.c @@ -25,6 +25,7 @@ # include <sys/time.h> #endif +#include <fcntl.h> #include <string.h> #include <signal.h> #include <stdlib.h> @@ -106,7 +107,7 @@ const char *strerror(int e) #endif #ifndef HAVE_UTIMES -int utimes(char *filename, struct timeval *tvp) +int utimes(const char *filename, struct timeval *tvp) { struct utimbuf ub; @@ -117,6 +118,108 @@ int utimes(char *filename, struct timeval *tvp) } #endif +#ifndef HAVE_UTIMENSAT +/* + * A limited implementation of utimensat() that only implements the + * functionality used by OpenSSH, currently only AT_FDCWD and + * AT_SYMLINK_NOFOLLOW. + */ +int +utimensat(int fd, const char *path, const struct timespec times[2], + int flag) +{ + struct timeval tv[2]; +# ifdef HAVE_FUTIMES + int ret, oflags = O_WRONLY; +# endif + + tv[0].tv_sec = times[0].tv_sec; + tv[0].tv_usec = times[0].tv_nsec / 1000; + tv[1].tv_sec = times[1].tv_sec; + tv[1].tv_usec = times[1].tv_nsec / 1000; + + if (fd != AT_FDCWD) { + errno = ENOSYS; + return -1; + } +# ifndef HAVE_FUTIMES + return utimes(path, tv); +# else +# ifdef O_NOFOLLOW + if (flag & AT_SYMLINK_NOFOLLOW) + oflags |= O_NOFOLLOW; +# endif /* O_NOFOLLOW */ + if ((fd = open(path, oflags)) == -1) + return -1; + ret = futimes(fd, tv); + close(fd); + return ret; +# endif +} +#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(path, owner, group); +# else +# ifdef O_NOFOLLOW + if (flag & AT_SYMLINK_NOFOLLOW) + oflags |= O_NOFOLLOW; +# endif /* 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 chmod(path, mode); +# else +# ifdef O_NOFOLLOW + if (flag & AT_SYMLINK_NOFOLLOW) + oflags |= O_NOFOLLOW; +# endif /* 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) { @@ -309,6 +412,14 @@ getsid(pid_t pid) } #endif +#ifndef HAVE_KILLPG +int +killpg(pid_t pgrp, int sig) +{ + return kill(pgrp, sig); +} +#endif + #ifdef FFLUSH_NULL_BUG #undef fflush int _ssh_compat_fflush(FILE *f) @@ -325,3 +436,25 @@ int _ssh_compat_fflush(FILE *f) return fflush(f); } #endif + +#ifndef HAVE_LOCALTIME_R +struct tm * +localtime_r(const time_t *timep, struct tm *result) +{ + struct tm *tm = localtime(timep); + *result = *tm; + return result; +} +#endif + +#ifdef ASAN_OPTIONS +const char *__asan_default_options(void) { + return ASAN_OPTIONS; +} +#endif + +#ifdef MSAN_OPTIONS +const char *__msan_default_options(void) { + return MSAN_OPTIONS; +} +#endif |