support linux kernel apis (new archs) with old syscalls removed
authorRich Felker <dalias@aerifal.cx>
Fri, 30 May 2014 01:01:32 +0000 (21:01 -0400)
committerRich Felker <dalias@aerifal.cx>
Fri, 30 May 2014 01:01:32 +0000 (21:01 -0400)
such archs are expected to omit definitions of the SYS_* macros for
syscalls their kernels lack from arch/$ARCH/bits/syscall.h. the
preprocessor is then able to select the an appropriate implementation
for affected functions. two basic strategies are used on a
case-by-case basis:

where the old syscalls correspond to deprecated library-level
functions, the deprecated functions have been converted to wrappers
for the modern function, and the modern function has fallback code
(omitted at the preprocessor level on new archs) to make use of the
old syscalls if the new syscall fails with ENOSYS. this also improves
functionality on older kernels and eliminates the incentive to program
with deprecated library-level functions for the sake of compatibility
with older kernels.

in other situations where the old syscalls correspond to library-level
functions which are not deprecated but merely lack some new features,
such as the *at functions, the old syscalls are still used on archs
which support them. this may change at some point in the future if or
when fallback code is added to the new functions to make them usable
(possibly with reduced functionality) on old kernels.

39 files changed:
src/env/__libc_start_main.c
src/linux/epoll.c
src/linux/eventfd.c
src/linux/inotify.c
src/linux/signalfd.c
src/linux/utimes.c
src/process/fork.c
src/process/posix_spawn.c
src/select/poll.c
src/select/select.c
src/stat/chmod.c
src/stat/fchmod.c
src/stat/fchmodat.c
src/stat/futimesat.c
src/stat/lstat.c
src/stat/mkdir.c
src/stat/mknod.c
src/stat/stat.c
src/stat/utimensat.c
src/stdio/remove.c
src/stdio/rename.c
src/stdio/tempnam.c
src/stdio/tmpfile.c
src/stdio/tmpnam.c
src/time/utime.c
src/unistd/access.c
src/unistd/chown.c
src/unistd/dup2.c
src/unistd/dup3.c
src/unistd/fchown.c
src/unistd/getpgrp.c
src/unistd/lchown.c
src/unistd/link.c
src/unistd/pause.c
src/unistd/pipe.c
src/unistd/readlink.c
src/unistd/rmdir.c
src/unistd/symlink.c
src/unistd/unlink.c

index d7481c259f90f007330ffd8f115a615e6dc5368f..c10a3f353f6082469f075ce58ccf86b0e3f84e63 100644 (file)
@@ -1,6 +1,7 @@
 #include <elf.h>
 #include <poll.h>
 #include <fcntl.h>
+#include <signal.h>
 #include "syscall.h"
 #include "atomic.h"
 #include "libc.h"
@@ -48,7 +49,11 @@ void __init_libc(char **envp, char *pn)
                && !aux[AT_SECURE]) return;
 
        struct pollfd pfd[3] = { {.fd=0}, {.fd=1}, {.fd=2} };
+#ifdef SYS_poll
        __syscall(SYS_poll, pfd, 3, 0);
+#else
+       __syscall(SYS_ppoll, pfd, 3, &(struct timespec){0}, 0, _NSIG/8);
+#endif
        for (i=0; i<3; i++) if (pfd[i].revents&POLLNVAL)
                if (__sys_open("/dev/null", O_RDWR)<0)
                        a_crash();
index 030786d3ff993d1be6ebce1df77a8aca5a8b571b..b45344fb31ab262179f6d8bf3d72b9239323910d 100644 (file)
@@ -4,12 +4,16 @@
 
 int epoll_create(int size)
 {
-       return syscall(SYS_epoll_create, size);
+       return epoll_create1(0);
 }
 
 int epoll_create1(int flags)
 {
-       return syscall(SYS_epoll_create1, flags);
+       int r = __syscall(SYS_epoll_create1, flags);
+#ifdef SYS_epoll_create
+       if (r==-ENOSYS && !flags) r = __syscall(SYS_epoll_create, 1);
+#endif
+       return __syscall_ret(r);
 }
 
 int epoll_ctl(int fd, int op, int fd2, struct epoll_event *ev)
@@ -19,10 +23,14 @@ int epoll_ctl(int fd, int op, int fd2, struct epoll_event *ev)
 
 int epoll_pwait(int fd, struct epoll_event *ev, int cnt, int to, const sigset_t *sigs)
 {
-       return syscall(SYS_epoll_pwait, fd, ev, cnt, to, sigs, _NSIG/8);
+       int r = __syscall(SYS_epoll_pwait, fd, ev, cnt, to, sigs, _NSIG/8);
+#ifdef SYS_epoll_wait
+       if (r==-ENOSYS && !sigs) r = __syscall(SYS_epoll_wait, fd, ev, cnt, to);
+#endif
+       return __syscall_ret(r);
 }
 
 int epoll_wait(int fd, struct epoll_event *ev, int cnt, int to)
 {
-       return syscall(SYS_epoll_wait, fd, ev, cnt, to);
+       return epoll_pwait(fd, ev, cnt, to, 0);
 }
index 530664874f6988caced5c29d61052f34420d5df9..3996803428b24b9fdc2efe64f731019822f975e9 100644 (file)
@@ -4,7 +4,11 @@
 
 int eventfd(unsigned int count, int flags)
 {
-       return syscall(flags ? SYS_eventfd2 : SYS_eventfd, count, flags);
+       int r = __syscall(SYS_eventfd2, count, flags);
+#ifdef SYS_eventfd
+       if (r==-ENOSYS && !flags) r = __syscall(SYS_eventfd, count);
+#endif
+       return __syscall_ret(r);
 }
 
 int eventfd_read(int fd, eventfd_t *value)
index a417c891fdf73603363b3ef7c0a2513881d4967b..84a5615494d7353d6a0f585ef532da5a7c0d11a0 100644 (file)
@@ -3,11 +3,15 @@
 
 int inotify_init()
 {
-       return syscall(SYS_inotify_init);
+       return inotify_init1(0);
 }
 int inotify_init1(int flags)
 {
-       return syscall(SYS_inotify_init1, flags);
+       int r = __syscall(SYS_inotify_init1, flags);
+#ifdef SYS_inotify_init
+       if (r==-ENOSYS && !flags) r = __syscall(SYS_inotify_init);
+#endif
+       return __syscall_ret(r);
 }
 
 int inotify_add_watch(int fd, const char *pathname, uint32_t mask)
index da6bcedb3f905ce00659f1b0e68855669541bce8..4bf43326fe5a7ee55858e728cf5bcff07bb64667 100644 (file)
@@ -7,6 +7,7 @@
 int signalfd(int fd, const sigset_t *sigs, int flags)
 {
        int ret = __syscall(SYS_signalfd4, fd, sigs, _NSIG/8, flags);
+#ifdef SYS_signalfd
        if (ret != -ENOSYS) return __syscall_ret(ret);
        ret = __syscall(SYS_signalfd, fd, sigs, _NSIG/8);
        if (ret >= 0) {
@@ -15,5 +16,6 @@ int signalfd(int fd, const sigset_t *sigs, int flags)
                if (flags & SFD_NONBLOCK)
                        __syscall(SYS_fcntl, ret, F_SETFL, O_NONBLOCK);
        }
+#endif
        return __syscall_ret(ret);
 }
index 70c0695f88a8ee3b102ff1d9b9c2dfa4727cbd94..b814c88b2fdefaea889fb885a34f5fd6faf8171e 100644 (file)
@@ -1,7 +1,10 @@
 #include <sys/time.h>
+#include "fcntl.h"
 #include "syscall.h"
 
+int __futimesat(int, const char *, const struct timeval [2]);
+
 int utimes(const char *path, const struct timeval times[2])
 {
-       return syscall(SYS_utimes, path, times);
+       return __futimesat(AT_FDCWD, path, times);
 }
index 864c7d7a6661e160e4bf652220c08ea3401c6325..f8cf21e7ca01d94cd67a2add5bcda4ccaff7af40 100644 (file)
@@ -1,5 +1,6 @@
 #include <unistd.h>
 #include <string.h>
+#include <signal.h>
 #include "syscall.h"
 #include "libc.h"
 #include "pthread_impl.h"
@@ -16,7 +17,11 @@ pid_t fork(void)
        sigset_t set;
        __fork_handler(-1);
        __block_all_sigs(&set);
+#ifdef SYS_fork
        ret = syscall(SYS_fork);
+#else
+       ret = syscall(SYS_clone, SIGCHLD, 0);
+#endif
        if (libc.has_thread_pointer && !ret) {
                pthread_t self = __pthread_self();
                self->tid = self->pid = __syscall(SYS_getpid);
index 08644f517fec90cb11ae164f2ff938e170108323..08928b0e7e72d7e3ed7cb50b364b2797637fd800 100644 (file)
@@ -22,6 +22,20 @@ struct args {
 
 void __get_handler_set(sigset_t *);
 
+static int __sys_dup2(int old, int new)
+{
+#ifdef SYS_dup2
+       return __syscall(SYS_dup2, old, new);
+#else
+       if (old==new) {
+               int r = __syscall(SYS_fcntl, old, F_GETFD);
+               return r<0 ? r : old;
+       } else {
+               return __syscall(SYS_dup3, old, new, 0);
+       }
+#endif
+}
+
 static int child(void *args_vp)
 {
        int i, ret;
@@ -92,14 +106,14 @@ static int child(void *args_vp)
                                        goto fail;
                                break;
                        case FDOP_DUP2:
-                               if ((ret=__syscall(SYS_dup2, op->srcfd, op->fd))<0)
+                               if ((ret=__sys_dup2(op->srcfd, op->fd))<0)
                                        goto fail;
                                break;
                        case FDOP_OPEN:
                                fd = __sys_open(op->path, op->oflag, op->mode);
                                if ((ret=fd) < 0) goto fail;
                                if (fd != op->fd) {
-                                       if ((ret=__syscall(SYS_dup2, fd, op->fd))<0)
+                                       if ((ret=__sys_dup2(fd, op->fd))<0)
                                                goto fail;
                                        __syscall(SYS_close, fd);
                                }
index f1e73e82f75d076f9c7cd32daed202a4f05908cf..9e0bcbd804f329031e6040b566290eb96e8b802a 100644 (file)
@@ -1,8 +1,16 @@
 #include <poll.h>
+#include <time.h>
+#include <signal.h>
 #include "syscall.h"
 #include "libc.h"
 
 int poll(struct pollfd *fds, nfds_t n, int timeout)
 {
+#ifdef SYS_poll
        return syscall_cp(SYS_poll, fds, n, timeout);
+#else
+       return syscall_cp(SYS_ppoll, fds, n, timeout>=0 ?
+               &((struct timespec){ .tv_sec = timeout/1000,
+               .tv_nsec = timeout%1000*1000000 }) : 0, 0, _NSIG/8);
+#endif
 }
index f93597b55cf78012a61b5d047c153e82bb1265e2..7b5f6dcf7a53aaf435db3221d4cd0d7db8f2abd7 100644 (file)
@@ -1,8 +1,26 @@
 #include <sys/select.h>
+#include <signal.h>
+#include <stdint.h>
+#include <errno.h>
 #include "syscall.h"
 #include "libc.h"
 
 int select(int n, fd_set *restrict rfds, fd_set *restrict wfds, fd_set *restrict efds, struct timeval *restrict tv)
 {
+#ifdef SYS_select
        return syscall_cp(SYS_select, n, rfds, wfds, efds, tv);
+#else
+       syscall_arg_t data[2] = { 0, _NSIG/8 };
+       struct timespec ts;
+       if (tv) {
+               if (tv->tv_sec < 0 || tv->tv_usec < 0)
+                       return __syscall_ret(-EINVAL);
+               time_t extra_secs = tv->tv_usec / 1000000;
+               ts.tv_nsec = tv->tv_usec % 1000000 * 1000;
+               const time_t max_time = (1ULL<<8*sizeof(time_t)-1)-1;
+               ts.tv_sec = extra_secs > max_time - tv->tv_sec ?
+                       max_time : tv->tv_sec + extra_secs;
+       }
+       return syscall_cp(SYS_pselect6, n, rfds, wfds, efds, tv ? &ts : 0, data);
+#endif
 }
index beb66e59d0611cfbe08b0bf5aad6888fc9df32ee..d4f53c564e14701ea360a7159037c39838266d9f 100644 (file)
@@ -1,7 +1,12 @@
 #include <sys/stat.h>
+#include <fcntl.h>
 #include "syscall.h"
 
 int chmod(const char *path, mode_t mode)
 {
+#ifdef SYS_chmod
        return syscall(SYS_chmod, path, mode);
+#else
+       return syscall(SYS_fchmodat, AT_FDCWD, path, mode);
+#endif
 }
index 6d2814162ebc296d99d100afcccaf64f74ea080c..93e1b64c57f9046b5446292360f1564611307db7 100644 (file)
@@ -13,5 +13,9 @@ int fchmod(int fd, mode_t mode)
 
        char buf[15+3*sizeof(int)];
        __procfdname(buf, fd);
+#ifdef SYS_chmod
        return syscall(SYS_chmod, buf, mode);
+#else
+       return syscall(SYS_fchmodat, AT_FDCWD, buf, mode);
+#endif
 }
index 12e7ff0cd17f90209cfb979c7a7096e2767e052a..afa6d44b5401da8caec81c3cb78dea9b344b4748 100644 (file)
@@ -28,8 +28,9 @@ int fchmodat(int fd, const char *path, mode_t mode, int flag)
        }
 
        __procfdname(proc, fd2);
-       if (!(ret = __syscall(SYS_stat, proc, &st)) && !S_ISLNK(st.st_mode))
-               ret = __syscall(SYS_chmod, proc, mode);
+       ret = __syscall(SYS_fstatat, AT_FDCWD, proc, &st, 0);
+       if (!ret && !S_ISLNK(st.st_mode))
+               ret = __syscall(SYS_fchmodat, AT_FDCWD, proc, mode);
 
        __syscall(SYS_close, fd2);
        return __syscall_ret(ret);
index dbefc844c46e092067a4650a8db1e59857192269..b4eea1d3c440be057012e0ef82efc38ad74219d9 100644 (file)
@@ -1,10 +1,23 @@
 #define _GNU_SOURCE
 #include <sys/time.h>
+#include <sys/stat.h>
+#include <errno.h>
 #include "syscall.h"
+#include "libc.h"
 
-#ifdef SYS_futimesat
-int futimesat(int dirfd, const char *pathname, const struct timeval times[2])
+int __futimesat(int dirfd, const char *pathname, const struct timeval times[2])
 {
-       return syscall(SYS_futimesat, dirfd, pathname, times);
+       struct timespec ts[2];
+       if (times) {
+               int i;
+               for (i=0; i<2; i++) {
+                       if (times[i].tv_usec >= 1000000ULL)
+                               return __syscall_ret(-EINVAL);
+                       ts[i].tv_sec = times[i].tv_sec;
+                       ts[i].tv_nsec = times[i].tv_usec * 1000;
+               }
+       }
+       return utimensat(dirfd, pathname, times ? ts : 0, 0);
 }
-#endif
+
+weak_alias(__futimesat, futimesat);
index 8f60358c19c19e9df8e5df653522b98935eb411b..5e8b84fcffad624fb426986681996a575b3f87f8 100644 (file)
@@ -1,10 +1,15 @@
 #include <sys/stat.h>
+#include <fcntl.h>
 #include "syscall.h"
 #include "libc.h"
 
 int lstat(const char *restrict path, struct stat *restrict buf)
 {
+#ifdef SYS_lstat
        return syscall(SYS_lstat, path, buf);
+#else
+       return syscall(SYS_fstatat, AT_FDCWD, path, buf, AT_SYMLINK_NOFOLLOW);
+#endif
 }
 
 LFS64(lstat);
index 770e1cccea8896c966f39fa77d191b8d3b1db5f7..32625b7de32768dc45916b76c0d063af89e1203c 100644 (file)
@@ -1,7 +1,12 @@
 #include <sys/stat.h>
+#include <fcntl.h>
 #include "syscall.h"
 
 int mkdir(const char *path, mode_t mode)
 {
+#ifdef SYS_mkdir
        return syscall(SYS_mkdir, path, mode);
+#else
+       return syscall(SYS_mkdirat, AT_FDCWD, path, mode);
+#endif
 }
index c3196571f0806a4b220abbba13b094acf75ed39a..beebd84e08995c36064ea67706ab7e48d95a48a1 100644 (file)
@@ -1,7 +1,12 @@
 #include <sys/stat.h>
+#include <fcntl.h>
 #include "syscall.h"
 
 int mknod(const char *path, mode_t mode, dev_t dev)
 {
+#ifdef SYS_mknod
        return syscall(SYS_mknod, path, mode, dev);
+#else
+       return syscall(SYS_mknodat, AT_FDCWD, path, mode, dev);
+#endif
 }
index c6de7168dfda86343b0ec16a5c7c6fa05a773e55..b4433a0a7cd13893b6889e89cfc3eac7e98178d1 100644 (file)
@@ -1,10 +1,15 @@
 #include <sys/stat.h>
+#include <fcntl.h>
 #include "syscall.h"
 #include "libc.h"
 
 int stat(const char *restrict path, struct stat *restrict buf)
 {
+#ifdef SYS_stat
        return syscall(SYS_stat, path, buf);
+#else
+       return syscall(SYS_fstatat, AT_FDCWD, path, buf, 0);
+#endif
 }
 
 LFS64(stat);
index 929698bcc47de1168db21422d66088207a572c9e..159c8be3b3c71109f2b72c36cc2c4027683a8cf6 100644 (file)
@@ -1,7 +1,37 @@
 #include <sys/stat.h>
+#include <sys/time.h>
+#include <fcntl.h>
+#include <errno.h>
 #include "syscall.h"
 
 int utimensat(int fd, const char *path, const struct timespec times[2], int flags)
 {
-       return syscall(SYS_utimensat, fd, path, times, flags);
+       int r = __syscall(SYS_utimensat, fd, path, times, flags);
+#ifdef SYS_futimesat
+       if (r != -ENOSYS || flags) return __syscall_ret(r);
+       struct timeval *tv = 0, tmp[2];
+       if (times) {
+               int i;
+               tv = tmp;
+               for (i=0; i<2; i++) {
+                       if (times[i].tv_nsec >= 1000000000ULL) {
+                               if (times[i].tv_nsec == UTIME_NOW &&
+                                   times[1-i].tv_nsec == UTIME_NOW) {
+                                       tv = 0;
+                                       break;
+                               }
+                               if (times[i].tv_nsec == UTIME_OMIT)
+                                       return __syscall_ret(-ENOSYS);
+                               return __syscall_ret(-EINVAL);
+                       }
+                       tmp[i].tv_sec = times[i].tv_sec;
+                       tmp[i].tv_usec = times[i].tv_nsec / 1000;
+               }
+       }
+
+       r = __syscall(SYS_futimesat, fd, path, tv);
+       if (r != -ENOSYS || fd != AT_FDCWD) return __syscall_ret(r);
+       r = __syscall(SYS_utimes, path, tv);
+#endif
+       return __syscall_ret(r);
 }
index e147ba251440d8e04d8585604c8190891b1643ac..942e301a4c035f491c6b0ffef47b8e1572312678 100644 (file)
@@ -1,9 +1,19 @@
 #include <stdio.h>
 #include <errno.h>
+#include <fcntl.h>
 #include "syscall.h"
 
 int remove(const char *path)
 {
-       int r = syscall(SYS_unlink, path);
-       return (r && errno == EISDIR) ? syscall(SYS_rmdir, path) : r;
+#ifdef SYS_unlink
+       int r = __syscall(SYS_unlink, path);
+#else
+       int r = __syscall(SYS_unlinkat, AT_FDCWD, path, 0);
+#endif
+#ifdef SYS_rmdir
+       if (r==-EISDIR) r = __syscall(SYS_rmdir, path);
+#else
+       if (r==-EISDIR) r = __syscall(SYS_unlinkat, AT_FDCWD, path, AT_REMOVEDIR);
+#endif
+       return __syscall_ret(r);
 }
index 97f14535e0081109c27de7e135c9359c7b12087a..04c90c01343a4b84beb5cf56b348e5d5041905ed 100644 (file)
@@ -1,7 +1,12 @@
 #include <stdio.h>
+#include <fcntl.h>
 #include "syscall.h"
 
 int rename(const char *old, const char *new)
 {
+#ifdef SYS_rename
        return syscall(SYS_rename, old, new);
+#else
+       return syscall(SYS_renameat, AT_FDCWD, old, AT_FDCWD, new);
+#endif
 }
index 9bf8c727e718df945e4c7a014ed601c92dbb7fbc..45a5f266100db36970b528fadbd1ffac710f9cf8 100644 (file)
@@ -36,7 +36,12 @@ char *tempnam(const char *dir, const char *pfx)
 
        for (try=0; try<MAXTRIES; try++) {
                __randname(s+l-6);
+#ifdef SYS_lstat
                r = __syscall(SYS_lstat, s, &(struct stat){0});
+#else
+               r = __syscall(SYS_fstatat, AT_FDCWD, s,
+                       &(struct stat){0}, AT_SYMLINK_NOFOLLOW);
+#endif
                if (r == -ENOENT) return strdup(s);
        }
        return 0;
index c8569948d7ff14d4c996f32fb132fb9c0cd371fc..a7d0000aecaeec7b9bae5e4fe235286706b22bf4 100644 (file)
@@ -17,7 +17,11 @@ FILE *tmpfile(void)
                fd = sys_open(s, O_RDWR|O_CREAT|O_EXCL, 0600);
                if (fd >= 0) {
                        f = __fdopen(fd, "w+");
+#ifdef SYS_unlink
                        __syscall(SYS_unlink, s);
+#else
+                       __syscall(SYS_unlinkat, AT_FDCWD, s, 0);
+#endif
                        return f;
                }
        }
index c3f5a2fff47b100c3cf698f7bb839fb151f06200..449eb9b0708c2a5d295db76f1e944059f6789f9b 100644 (file)
@@ -17,7 +17,12 @@ char *tmpnam(char *buf)
        int r;
        for (try=0; try<MAXTRIES; try++) {
                __randname(s+12);
+#ifdef SYS_lstat
                r = __syscall(SYS_lstat, s, &(struct stat){0});
+#else
+               r = __syscall(SYS_fstatat, AT_FDCWD, s,
+                       &(struct stat){0}, AT_SYMLINK_NOFOLLOW);
+#endif
                if (r == -ENOENT) return strcpy(buf ? buf : internal, s);
        }
        return 0;
index b2b5741b32099a63b2b02ecb275377b6f9e32f23..e7592b297809c817a2ec9ca4368be1f37147920b 100644 (file)
@@ -1,14 +1,11 @@
 #include <utime.h>
-#include <sys/time.h>
-#include "syscall.h"
+#include <sys/stat.h>
+#include <time.h>
+#include <fcntl.h>
 
 int utime(const char *path, const struct utimbuf *times)
 {
-       if (times) {
-               struct timeval tv[2] = {
-                       { .tv_sec = times->actime },
-                       { .tv_sec = times->modtime } };
-               return syscall(SYS_utimes, path, tv);
-       }
-       return syscall(SYS_utimes, path, 0);
+       return utimensat(AT_FDCWD, path, times ? ((struct timespec [2]){
+               { .tv_sec = times->actime }, { .tv_sec = times->modtime }})
+               : 0, 0);
 }
index e7ce73a2a7ab9a44b57b6bd64860f57276b7e520..d6eed6839822f32bebf333218b6e020d08bbbd28 100644 (file)
@@ -1,7 +1,12 @@
 #include <unistd.h>
+#include <fcntl.h>
 #include "syscall.h"
 
 int access(const char *filename, int amode)
 {
+#ifdef SYS_access
        return syscall(SYS_access, filename, amode);
+#else
+       return syscall(SYS_faccessat, AT_FDCWD, filename, amode, 0);
+#endif
 }
index 95f6f61e9eb1470a997b771e8102d457a55923dd..14b032550d675e6594302a6107c13a599d57443a 100644 (file)
@@ -1,7 +1,12 @@
 #include <unistd.h>
+#include <fcntl.h>
 #include "syscall.h"
 
 int chown(const char *path, uid_t uid, gid_t gid)
 {
+#ifdef SYS_chown
        return syscall(SYS_chown, path, uid, gid);
+#else
+       return syscall(SYS_fchownat, AT_FDCWD, path, uid, gid, 0);
+#endif
 }
index 87a0d44538eb49162bf4d26824b0d35de19af0fb..8f43c6ddfe8983e9565d6a14a10f423c9fd55f05 100644 (file)
@@ -1,10 +1,20 @@
 #include <unistd.h>
 #include <errno.h>
+#include <fcntl.h>
 #include "syscall.h"
 
 int dup2(int old, int new)
 {
        int r;
+#ifdef SYS_dup2
        while ((r=__syscall(SYS_dup2, old, new))==-EBUSY);
+#else
+       if (old==new) {
+               r = __syscall(SYS_fcntl, old, F_GETFD);
+               if (r >= 0) return old;
+       } else {
+               while ((r=__syscall(SYS_dup3, old, new, 0))==-EBUSY);
+       }
+#endif
        return __syscall_ret(r);
 }
index 1f7134b3dcbf7ea16390b543f38798c4b33549b0..0eb6caf59e6e1b0015b231632b6c20f879c5ad95 100644 (file)
@@ -8,6 +8,7 @@
 int __dup3(int old, int new, int flags)
 {
        int r;
+#ifdef SYS_dup2
        if (old==new) return __syscall_ret(-EINVAL);
        if (flags & O_CLOEXEC) {
                while ((r=__syscall(SYS_dup3, old, new, flags))==-EBUSY);
@@ -15,6 +16,9 @@ int __dup3(int old, int new, int flags)
        }
        while ((r=__syscall(SYS_dup2, old, new))==-EBUSY);
        if (flags & O_CLOEXEC) __syscall(SYS_fcntl, new, F_SETFD, FD_CLOEXEC);
+#else
+       while ((r=__syscall(SYS_dup3, old, new, flags))==-EBUSY);
+#endif
        return __syscall_ret(r);
 }
 
index 36633b0e95f3145a3cacf33958dd3862ced78b68..03459849e50a3436d5bec51a4763375e05c4796d 100644 (file)
@@ -13,5 +13,10 @@ int fchown(int fd, uid_t uid, gid_t gid)
 
        char buf[15+3*sizeof(int)];
        __procfdname(buf, fd);
+#ifdef SYS_chown
        return syscall(SYS_chown, buf, uid, gid);
+#else
+       return syscall(SYS_fchownat, AT_FDCWD, buf, uid, gid);
+#endif
+
 }
index 433f42e8f816107d75b64a096cb54b89e7688bb4..90e9bb07f6e3e19378957524d425847cec6df1c5 100644 (file)
@@ -3,5 +3,5 @@
 
 pid_t getpgrp(void)
 {
-       return __syscall(SYS_getpgrp);
+       return __syscall(SYS_getpgid, 0);
 }
index de871aebb2155826716ee13a5d7e71ca0b0ad32d..ccd5ee0255eea2af0dcec6f134e21ce07a896faf 100644 (file)
@@ -1,7 +1,12 @@
 #include <unistd.h>
+#include <fcntl.h>
 #include "syscall.h"
 
 int lchown(const char *path, uid_t uid, gid_t gid)
 {
+#ifdef SYS_lchown
        return syscall(SYS_lchown, path, uid, gid);
+#else
+       return syscall(SYS_fchownat, AT_FDCWD, path, uid, gid, AT_SYMLINK_NOFOLLOW);
+#endif
 }
index 20193f2ac831b5e72e3f8d92aa9a54ba5b94bda0..feec18e533d9595a2f37dd7fc8005b37c79b60ed 100644 (file)
@@ -1,7 +1,12 @@
 #include <unistd.h>
+#include <fcntl.h>
 #include "syscall.h"
 
 int link(const char *existing, const char *new)
 {
+#ifdef SYS_link
        return syscall(SYS_link, existing, new);
+#else
+       return syscall(SYS_linkat, AT_FDCWD, existing, AT_FDCWD, new, 0);
+#endif
 }
index f7ed17d16f0fdc481d1bc6d3df37c72eeb82989d..56eb171e0ac48c46857d0f82a38bf697e0dabfea 100644 (file)
@@ -1,8 +1,13 @@
 #include <unistd.h>
+#include <signal.h>
 #include "syscall.h"
 #include "libc.h"
 
 int pause(void)
 {
+#ifdef SYS_pause
        return syscall_cp(SYS_pause);
+#else
+       return syscall_cp(SYS_ppoll, 0, 0, 0, 0);
+#endif
 }
index 36c6f13e7a1684acb6340f4e59338d99fd9fcf32..d07b8d24ae3b1f55126700e64994ab55d453fb16 100644 (file)
@@ -3,5 +3,9 @@
 
 int pipe(int fd[2])
 {
+#ifdef SYS_pipe
        return syscall(SYS_pipe, fd);
+#else
+       return syscall(SYS_pipe2, fd, 0);
+#endif
 }
index ec291e3dfd320c4045e6f4f372e60944aa5a6040..a152d52492ed775d3d8fd57125423e461bfb20d8 100644 (file)
@@ -1,7 +1,12 @@
 #include <unistd.h>
+#include <fcntl.h>
 #include "syscall.h"
 
 ssize_t readlink(const char *restrict path, char *restrict buf, size_t bufsize)
 {
+#ifdef SYS_readlink
        return syscall(SYS_readlink, path, buf, bufsize);
+#else
+       return syscall(SYS_readlinkat, AT_FDCWD, path, buf, bufsize);
+#endif
 }
index dfe1605d05173460c395e97eb7968da6a4698997..6825ffc8359a557790d278c8827061b9ed18564a 100644 (file)
@@ -1,7 +1,12 @@
 #include <unistd.h>
+#include <fcntl.h>
 #include "syscall.h"
 
 int rmdir(const char *path)
 {
+#ifdef SYS_rmdir
        return syscall(SYS_rmdir, path);
+#else
+       return syscall(SYS_unlinkat, AT_FDCWD, path, AT_REMOVEDIR);
+#endif
 }
index 5902d45a1af556ce5de7ea32e17aafb68b2e8540..0973d78a8936bca2cef633f361abd2401bd82f4a 100644 (file)
@@ -1,7 +1,12 @@
 #include <unistd.h>
+#include <fcntl.h>
 #include "syscall.h"
 
 int symlink(const char *existing, const char *new)
 {
+#ifdef SYS_symlink
        return syscall(SYS_symlink, existing, new);
+#else
+       return syscall(SYS_symlinkat, existing, AT_FDCWD, new);
+#endif
 }
index bdb37bea02d7b5f4336d3212b7eb23db9e9dac25..c40c28d50be4e59951afb14dea3436f768e01cc1 100644 (file)
@@ -1,7 +1,12 @@
 #include <unistd.h>
+#include <fcntl.h>
 #include "syscall.h"
 
 int unlink(const char *path)
 {
+#ifdef SYS_unlink
        return syscall(SYS_unlink, path);
+#else
+       return syscall(SYS_unlinkat, AT_FDCWD, path, 0);
+#endif
 }