summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2014-05-29 21:01:32 -0400
committerRich Felker <dalias@aerifal.cx>2014-05-29 21:01:32 -0400
commitdd5f50da6f6c3df5647e922e47f8568a8896a752 (patch)
treec5ab9a1006d2ab4c449f8fa922ce3237acad30e4
parent2e55da911896a91e95b24ab5dc8a9d9b0718f4de (diff)
downloadmusl-dd5f50da6f6c3df5647e922e47f8568a8896a752.tar.gz
musl-dd5f50da6f6c3df5647e922e47f8568a8896a752.tar.bz2
musl-dd5f50da6f6c3df5647e922e47f8568a8896a752.tar.xz
musl-dd5f50da6f6c3df5647e922e47f8568a8896a752.zip
support linux kernel apis (new archs) with old syscalls removed
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.
-rw-r--r--src/env/__libc_start_main.c5
-rw-r--r--src/linux/epoll.c16
-rw-r--r--src/linux/eventfd.c6
-rw-r--r--src/linux/inotify.c8
-rw-r--r--src/linux/signalfd.c2
-rw-r--r--src/linux/utimes.c5
-rw-r--r--src/process/fork.c5
-rw-r--r--src/process/posix_spawn.c18
-rw-r--r--src/select/poll.c8
-rw-r--r--src/select/select.c18
-rw-r--r--src/stat/chmod.c5
-rw-r--r--src/stat/fchmod.c4
-rw-r--r--src/stat/fchmodat.c5
-rw-r--r--src/stat/futimesat.c21
-rw-r--r--src/stat/lstat.c5
-rw-r--r--src/stat/mkdir.c5
-rw-r--r--src/stat/mknod.c5
-rw-r--r--src/stat/stat.c5
-rw-r--r--src/stat/utimensat.c32
-rw-r--r--src/stdio/remove.c14
-rw-r--r--src/stdio/rename.c5
-rw-r--r--src/stdio/tempnam.c5
-rw-r--r--src/stdio/tmpfile.c4
-rw-r--r--src/stdio/tmpnam.c5
-rw-r--r--src/time/utime.c15
-rw-r--r--src/unistd/access.c5
-rw-r--r--src/unistd/chown.c5
-rw-r--r--src/unistd/dup2.c10
-rw-r--r--src/unistd/dup3.c4
-rw-r--r--src/unistd/fchown.c5
-rw-r--r--src/unistd/getpgrp.c2
-rw-r--r--src/unistd/lchown.c5
-rw-r--r--src/unistd/link.c5
-rw-r--r--src/unistd/pause.c5
-rw-r--r--src/unistd/pipe.c4
-rw-r--r--src/unistd/readlink.c5
-rw-r--r--src/unistd/rmdir.c5
-rw-r--r--src/unistd/symlink.c5
-rw-r--r--src/unistd/unlink.c5
39 files changed, 267 insertions, 29 deletions
diff --git a/src/env/__libc_start_main.c b/src/env/__libc_start_main.c
index d7481c25..c10a3f35 100644
--- a/src/env/__libc_start_main.c
+++ b/src/env/__libc_start_main.c
@@ -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();
diff --git a/src/linux/epoll.c b/src/linux/epoll.c
index 030786d3..b45344fb 100644
--- a/src/linux/epoll.c
+++ b/src/linux/epoll.c
@@ -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);
}
diff --git a/src/linux/eventfd.c b/src/linux/eventfd.c
index 53066487..39968034 100644
--- a/src/linux/eventfd.c
+++ b/src/linux/eventfd.c
@@ -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)
diff --git a/src/linux/inotify.c b/src/linux/inotify.c
index a417c891..84a56154 100644
--- a/src/linux/inotify.c
+++ b/src/linux/inotify.c
@@ -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)
diff --git a/src/linux/signalfd.c b/src/linux/signalfd.c
index da6bcedb..4bf43326 100644
--- a/src/linux/signalfd.c
+++ b/src/linux/signalfd.c
@@ -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);
}
diff --git a/src/linux/utimes.c b/src/linux/utimes.c
index 70c0695f..b814c88b 100644
--- a/src/linux/utimes.c
+++ b/src/linux/utimes.c
@@ -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);
}
diff --git a/src/process/fork.c b/src/process/fork.c
index 864c7d7a..f8cf21e7 100644
--- a/src/process/fork.c
+++ b/src/process/fork.c
@@ -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);
diff --git a/src/process/posix_spawn.c b/src/process/posix_spawn.c
index 08644f51..08928b0e 100644
--- a/src/process/posix_spawn.c
+++ b/src/process/posix_spawn.c
@@ -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);
}
diff --git a/src/select/poll.c b/src/select/poll.c
index f1e73e82..9e0bcbd8 100644
--- a/src/select/poll.c
+++ b/src/select/poll.c
@@ -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
}
diff --git a/src/select/select.c b/src/select/select.c
index f93597b5..7b5f6dcf 100644
--- a/src/select/select.c
+++ b/src/select/select.c
@@ -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
}
diff --git a/src/stat/chmod.c b/src/stat/chmod.c
index beb66e59..d4f53c56 100644
--- a/src/stat/chmod.c
+++ b/src/stat/chmod.c
@@ -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
}
diff --git a/src/stat/fchmod.c b/src/stat/fchmod.c
index 6d281416..93e1b64c 100644
--- a/src/stat/fchmod.c
+++ b/src/stat/fchmod.c
@@ -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
}
diff --git a/src/stat/fchmodat.c b/src/stat/fchmodat.c
index 12e7ff0c..afa6d44b 100644
--- a/src/stat/fchmodat.c
+++ b/src/stat/fchmodat.c
@@ -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);
diff --git a/src/stat/futimesat.c b/src/stat/futimesat.c
index dbefc844..b4eea1d3 100644
--- a/src/stat/futimesat.c
+++ b/src/stat/futimesat.c
@@ -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);
diff --git a/src/stat/lstat.c b/src/stat/lstat.c
index 8f60358c..5e8b84fc 100644
--- a/src/stat/lstat.c
+++ b/src/stat/lstat.c
@@ -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);
diff --git a/src/stat/mkdir.c b/src/stat/mkdir.c
index 770e1ccc..32625b7d 100644
--- a/src/stat/mkdir.c
+++ b/src/stat/mkdir.c
@@ -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
}
diff --git a/src/stat/mknod.c b/src/stat/mknod.c
index c3196571..beebd84e 100644
--- a/src/stat/mknod.c
+++ b/src/stat/mknod.c
@@ -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
}
diff --git a/src/stat/stat.c b/src/stat/stat.c
index c6de7168..b4433a0a 100644
--- a/src/stat/stat.c
+++ b/src/stat/stat.c
@@ -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);
diff --git a/src/stat/utimensat.c b/src/stat/utimensat.c
index 929698bc..159c8be3 100644
--- a/src/stat/utimensat.c
+++ b/src/stat/utimensat.c
@@ -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);
}
diff --git a/src/stdio/remove.c b/src/stdio/remove.c
index e147ba25..942e301a 100644
--- a/src/stdio/remove.c
+++ b/src/stdio/remove.c
@@ -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);
}
diff --git a/src/stdio/rename.c b/src/stdio/rename.c
index 97f14535..04c90c01 100644
--- a/src/stdio/rename.c
+++ b/src/stdio/rename.c
@@ -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
}
diff --git a/src/stdio/tempnam.c b/src/stdio/tempnam.c
index 9bf8c727..45a5f266 100644
--- a/src/stdio/tempnam.c
+++ b/src/stdio/tempnam.c
@@ -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;
diff --git a/src/stdio/tmpfile.c b/src/stdio/tmpfile.c
index c8569948..a7d0000a 100644
--- a/src/stdio/tmpfile.c
+++ b/src/stdio/tmpfile.c
@@ -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;
}
}
diff --git a/src/stdio/tmpnam.c b/src/stdio/tmpnam.c
index c3f5a2ff..449eb9b0 100644
--- a/src/stdio/tmpnam.c
+++ b/src/stdio/tmpnam.c
@@ -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;
diff --git a/src/time/utime.c b/src/time/utime.c
index b2b5741b..e7592b29 100644
--- a/src/time/utime.c
+++ b/src/time/utime.c
@@ -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);
}
diff --git a/src/unistd/access.c b/src/unistd/access.c
index e7ce73a2..d6eed683 100644
--- a/src/unistd/access.c
+++ b/src/unistd/access.c
@@ -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
}
diff --git a/src/unistd/chown.c b/src/unistd/chown.c
index 95f6f61e..14b03255 100644
--- a/src/unistd/chown.c
+++ b/src/unistd/chown.c
@@ -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
}
diff --git a/src/unistd/dup2.c b/src/unistd/dup2.c
index 87a0d445..8f43c6dd 100644
--- a/src/unistd/dup2.c
+++ b/src/unistd/dup2.c
@@ -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);
}
diff --git a/src/unistd/dup3.c b/src/unistd/dup3.c
index 1f7134b3..0eb6caf5 100644
--- a/src/unistd/dup3.c
+++ b/src/unistd/dup3.c
@@ -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);
}
diff --git a/src/unistd/fchown.c b/src/unistd/fchown.c
index 36633b0e..03459849 100644
--- a/src/unistd/fchown.c
+++ b/src/unistd/fchown.c
@@ -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
+
}
diff --git a/src/unistd/getpgrp.c b/src/unistd/getpgrp.c
index 433f42e8..90e9bb07 100644
--- a/src/unistd/getpgrp.c
+++ b/src/unistd/getpgrp.c
@@ -3,5 +3,5 @@
pid_t getpgrp(void)
{
- return __syscall(SYS_getpgrp);
+ return __syscall(SYS_getpgid, 0);
}
diff --git a/src/unistd/lchown.c b/src/unistd/lchown.c
index de871aeb..ccd5ee02 100644
--- a/src/unistd/lchown.c
+++ b/src/unistd/lchown.c
@@ -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
}
diff --git a/src/unistd/link.c b/src/unistd/link.c
index 20193f2a..feec18e5 100644
--- a/src/unistd/link.c
+++ b/src/unistd/link.c
@@ -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
}
diff --git a/src/unistd/pause.c b/src/unistd/pause.c
index f7ed17d1..56eb171e 100644
--- a/src/unistd/pause.c
+++ b/src/unistd/pause.c
@@ -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
}
diff --git a/src/unistd/pipe.c b/src/unistd/pipe.c
index 36c6f13e..d07b8d24 100644
--- a/src/unistd/pipe.c
+++ b/src/unistd/pipe.c
@@ -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
}
diff --git a/src/unistd/readlink.c b/src/unistd/readlink.c
index ec291e3d..a152d524 100644
--- a/src/unistd/readlink.c
+++ b/src/unistd/readlink.c
@@ -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
}
diff --git a/src/unistd/rmdir.c b/src/unistd/rmdir.c
index dfe1605d..6825ffc8 100644
--- a/src/unistd/rmdir.c
+++ b/src/unistd/rmdir.c
@@ -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
}
diff --git a/src/unistd/symlink.c b/src/unistd/symlink.c
index 5902d45a..0973d78a 100644
--- a/src/unistd/symlink.c
+++ b/src/unistd/symlink.c
@@ -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
}
diff --git a/src/unistd/unlink.c b/src/unistd/unlink.c
index bdb37bea..c40c28d5 100644
--- a/src/unistd/unlink.c
+++ b/src/unistd/unlink.c
@@ -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
}