소스 검색

in fcntl, avoid passing pointer arguments to syscalls as longs

really, fcntl should be changed to use the correct type corresponding
to cmd when calling va_arg, and to carry the correct type through
until making the syscall. however, this greatly increases binary size
and does not seem to offer any benefits except formal correctness, so
I'm holding off on that change for now.

the minimal changes made in this patch are in preparation for addition
of the x32 port, where the syscall macros need to know whether their
arguments are pointers or integers in order to properly pass them to
the 64-bit kernel.
Rich Felker 11 년 전
부모
커밋
131871a3d8
1개의 변경된 파일12개의 추가작업 그리고 3개의 파일을 삭제
  1. 12 3
      src/fcntl/fcntl.c

+ 12 - 3
src/fcntl/fcntl.c

@@ -13,11 +13,11 @@ int fcntl(int fd, int cmd, ...)
 	arg = va_arg(ap, long);
 	arg = va_arg(ap, long);
 	va_end(ap);
 	va_end(ap);
 	if (cmd == F_SETFL) arg |= O_LARGEFILE;
 	if (cmd == F_SETFL) arg |= O_LARGEFILE;
-	if (cmd == F_SETLKW) return syscall_cp(SYS_fcntl, fd, cmd, arg);
+	if (cmd == F_SETLKW) return syscall_cp(SYS_fcntl, fd, cmd, (void *)arg);
 	if (cmd == F_GETOWN) {
 	if (cmd == F_GETOWN) {
 		struct f_owner_ex ex;
 		struct f_owner_ex ex;
 		int ret = __syscall(SYS_fcntl, fd, F_GETOWN_EX, &ex);
 		int ret = __syscall(SYS_fcntl, fd, F_GETOWN_EX, &ex);
-		if (ret == -EINVAL) return __syscall(SYS_fcntl, fd, cmd, arg);
+		if (ret == -EINVAL) return __syscall(SYS_fcntl, fd, cmd, (void *)arg);
 		if (ret) return __syscall_ret(ret);
 		if (ret) return __syscall_ret(ret);
 		return ex.type == F_OWNER_PGRP ? -ex.pid : ex.pid;
 		return ex.type == F_OWNER_PGRP ? -ex.pid : ex.pid;
 	}
 	}
@@ -37,5 +37,14 @@ int fcntl(int fd, int cmd, ...)
 		if (ret >= 0) __syscall(SYS_fcntl, ret, F_SETFD, FD_CLOEXEC);
 		if (ret >= 0) __syscall(SYS_fcntl, ret, F_SETFD, FD_CLOEXEC);
 		return __syscall_ret(ret);
 		return __syscall_ret(ret);
 	}
 	}
-	return syscall(SYS_fcntl, fd, cmd, arg);
+	switch (cmd) {
+	case F_SETLK:
+	case F_SETLKW:
+	case F_GETLK:
+	case F_GETOWN_EX:
+	case F_SETOWN_EX:
+		return syscall(SYS_fcntl, fd, cmd, (void *)arg);
+	default:
+		return syscall(SYS_fcntl, fd, cmd, arg);
+	}
 }
 }