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.
This commit is contained in:
Rich Felker
2014-05-24 22:54:05 -04:00
parent 44d28e5512
commit 594c827a22
9 changed files with 26 additions and 10 deletions

View File

@ -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;
}

View File

@ -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);

View File

@ -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__))

View File

@ -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);

View File

@ -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)

View File

@ -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;

View File

@ -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);

View File

@ -14,7 +14,7 @@ FILE *tmpfile(void)
for (try=0; try<MAXTRIES; try++) {
s = tmpnam(buf);
if (!s) return 0;
fd = syscall(SYS_open, s, O_RDWR|O_CREAT|O_EXCL|O_LARGEFILE, 0600);
fd = sys_open(s, O_RDWR|O_CREAT|O_EXCL, 0600);
if (fd >= 0) {
f = __fdopen(fd, "w+");
__syscall(SYS_unlink, s);

View File

@ -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);