diff options
author | Rich Felker <dalias@aerifal.cx> | 2014-05-29 21:01:32 -0400 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2014-05-29 21:01:32 -0400 |
commit | dd5f50da6f6c3df5647e922e47f8568a8896a752 (patch) | |
tree | c5ab9a1006d2ab4c449f8fa922ce3237acad30e4 /src/stdio | |
parent | 2e55da911896a91e95b24ab5dc8a9d9b0718f4de (diff) | |
download | musl-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/stdio')
-rw-r--r-- | src/stdio/remove.c | 14 | ||||
-rw-r--r-- | src/stdio/rename.c | 5 | ||||
-rw-r--r-- | src/stdio/tempnam.c | 5 | ||||
-rw-r--r-- | src/stdio/tmpfile.c | 4 | ||||
-rw-r--r-- | src/stdio/tmpnam.c | 5 |
5 files changed, 31 insertions, 2 deletions
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; |