summaryrefslogtreecommitdiff
path: root/src/unistd
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 /src/unistd
parent2e55da911896a91e95b24ab5dc8a9d9b0718f4de (diff)
downloadmusl-dd5f50da6f6c3df5647e922e47f8568a8896a752.tar.gz
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.
Diffstat (limited to 'src/unistd')
-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
14 files changed, 69 insertions, 1 deletions
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
}