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.
This commit is contained in:
parent
2e55da9118
commit
dd5f50da6f
39 changed files with 267 additions and 29 deletions
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue