From 594c827a22124ae550b9a877b8188e0898dff8db Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Sat, 24 May 2014 22:54:05 -0400 Subject: [PATCH] support kernels with no SYS_open syscall, only SYS_openat open is handled specially because it is used from so many places, in so many variants (2 or 3 arguments, setting errno or not, and cancellable or not). trying to do it as a function would not only increase bloat, but would also risk subtle breakage. this is the first step towards supporting "new" archs where linux lacks "old" syscalls. --- src/env/__libc_start_main.c | 2 +- src/fcntl/open.c | 2 +- src/internal/syscall.h | 18 ++++++++++++++++++ src/misc/realpath.c | 2 +- src/process/posix_spawn.c | 3 +-- src/stdio/__fopen_rb_ca.c | 2 +- src/stdio/fopen.c | 2 +- src/stdio/tmpfile.c | 2 +- src/time/__map_file.c | 3 +-- 9 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/env/__libc_start_main.c b/src/env/__libc_start_main.c index 3498afbd..d7481c25 100644 --- a/src/env/__libc_start_main.c +++ b/src/env/__libc_start_main.c @@ -50,7 +50,7 @@ void __init_libc(char **envp, char *pn) struct pollfd pfd[3] = { {.fd=0}, {.fd=1}, {.fd=2} }; __syscall(SYS_poll, pfd, 3, 0); for (i=0; i<3; i++) if (pfd[i].revents&POLLNVAL) - if (__syscall(SYS_open, "/dev/null", O_RDWR|O_LARGEFILE)<0) + if (__sys_open("/dev/null", O_RDWR)<0) a_crash(); libc.secure = 1; } diff --git a/src/fcntl/open.c b/src/fcntl/open.c index be442089..0594ed7e 100644 --- a/src/fcntl/open.c +++ b/src/fcntl/open.c @@ -10,7 +10,7 @@ int open(const char *filename, int flags, ...) va_start(ap, flags); mode = va_arg(ap, mode_t); va_end(ap); - return syscall_cp(SYS_open, filename, flags|O_LARGEFILE, mode); + return sys_open_cp(filename, flags, mode); } LFS64(open); diff --git a/src/internal/syscall.h b/src/internal/syscall.h index 914b0d18..9dd92995 100644 --- a/src/internal/syscall.h +++ b/src/internal/syscall.h @@ -187,3 +187,21 @@ long __syscall_ret(unsigned long), __syscall(syscall_arg_t, ...), #define __SC_accept4 18 #define __SC_recvmmsg 19 #define __SC_sendmmsg 20 + +#ifdef SYS_open +#define __sys_open2(x,pn,fl) __syscall2(SYS_open, pn, (fl)|O_LARGEFILE) +#define __sys_open3(x,pn,fl,mo) __syscall3(SYS_open, pn, (fl)|O_LARGEFILE, mo) +#define __sys_open_cp2(x,pn,fl) __syscall_cp2(SYS_open, pn, (fl)|O_LARGEFILE) +#define __sys_open_cp3(x,pn,fl,mo) __syscall_cp3(SYS_open, pn, (fl)|O_LARGEFILE, mo) +#else +#define __sys_open2(x,pn,fl) __syscall2(SYS_openat, AT_FDCWD, pn, (fl)|O_LARGEFILE) +#define __sys_open3(x,pn,fl,mo) __syscall3(SYS_openat, AT_FDCWD, pn, (fl)|O_LARGEFILE, mo) +#define __sys_open_cp2(x,pn,fl) __syscall_cp2(SYS_openat, AT_FDCWD, pn, (fl)|O_LARGEFILE) +#define __sys_open_cp3(x,pn,fl,mo) __syscall_cp3(SYS_openat, AT_FDCWD, pn, (fl)|O_LARGEFILE, mo) +#endif + +#define __sys_open(...) __SYSCALL_DISP(__sys_open,,__VA_ARGS__) +#define sys_open(...) __syscall_ret(__sys_open(__VA_ARGS__)) + +#define __sys_open_cp(...) __SYSCALL_DISP(__sys_open_cp,,__VA_ARGS__) +#define sys_open_cp(...) __syscall_ret(__sys_open_cp(__VA_ARGS__)) diff --git a/src/misc/realpath.c b/src/misc/realpath.c index 4cc7e7de..88c849cd 100644 --- a/src/misc/realpath.c +++ b/src/misc/realpath.c @@ -22,7 +22,7 @@ char *realpath(const char *restrict filename, char *restrict resolved) return 0; } - fd = syscall(SYS_open, filename, O_PATH|O_NONBLOCK|O_CLOEXEC|O_LARGEFILE); + fd = sys_open(filename, O_PATH|O_NONBLOCK|O_CLOEXEC); if (fd < 0) return 0; __procfdname(buf, fd); diff --git a/src/process/posix_spawn.c b/src/process/posix_spawn.c index f675a13c..08644f51 100644 --- a/src/process/posix_spawn.c +++ b/src/process/posix_spawn.c @@ -96,8 +96,7 @@ static int child(void *args_vp) goto fail; break; case FDOP_OPEN: - fd = __syscall(SYS_open, op->path, - op->oflag | O_LARGEFILE, op->mode); + 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) diff --git a/src/stdio/__fopen_rb_ca.c b/src/stdio/__fopen_rb_ca.c index 9202c8ce..b72c6304 100644 --- a/src/stdio/__fopen_rb_ca.c +++ b/src/stdio/__fopen_rb_ca.c @@ -6,7 +6,7 @@ FILE *__fopen_rb_ca(const char *filename, FILE *f, unsigned char *buf, size_t le { memset(f, 0, sizeof *f); - f->fd = syscall(SYS_open, filename, O_RDONLY|O_LARGEFILE|O_CLOEXEC, 0); + f->fd = sys_open(filename, O_RDONLY|O_CLOEXEC); if (f->fd < 0) return 0; f->flags = F_NOWR | F_PERM; diff --git a/src/stdio/fopen.c b/src/stdio/fopen.c index da17ce8b..3d97cfa8 100644 --- a/src/stdio/fopen.c +++ b/src/stdio/fopen.c @@ -18,7 +18,7 @@ FILE *fopen(const char *restrict filename, const char *restrict mode) /* Compute the flags to pass to open() */ flags = __fmodeflags(mode); - fd = syscall_cp(SYS_open, filename, flags|O_LARGEFILE, 0666); + fd = sys_open_cp(filename, flags, 0666); if (fd < 0) return 0; f = __fdopen(fd, mode); diff --git a/src/stdio/tmpfile.c b/src/stdio/tmpfile.c index 926d6601..b0d0ba07 100644 --- a/src/stdio/tmpfile.c +++ b/src/stdio/tmpfile.c @@ -14,7 +14,7 @@ FILE *tmpfile(void) for (try=0; try= 0) { f = __fdopen(fd, "w+"); __syscall(SYS_unlink, s); diff --git a/src/time/__map_file.c b/src/time/__map_file.c index 84ae839f..d06a5814 100644 --- a/src/time/__map_file.c +++ b/src/time/__map_file.c @@ -9,8 +9,7 @@ const char unsigned *__map_file(const char *pathname, size_t *size) { struct stat st; const unsigned char *map = MAP_FAILED; - int flags = O_RDONLY|O_LARGEFILE|O_CLOEXEC|O_NONBLOCK; - int fd = __syscall(SYS_open, pathname, flags); + int fd = __sys_open(pathname, O_RDONLY|O_CLOEXEC|O_NONBLOCK); if (fd < 0) return 0; if (!__syscall(SYS_fstat, fd, &st)) map = __mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0); -- 2.25.1