瀏覽代碼

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.
Rich Felker 10 年之前
父節點
當前提交
594c827a22

+ 1 - 1
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;
 }

+ 1 - 1
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);

+ 18 - 0
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__))

+ 1 - 1
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);
 

+ 1 - 2
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)

+ 1 - 1
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;

+ 1 - 1
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);

+ 1 - 1
src/stdio/tmpfile.c

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

+ 1 - 2
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);