فهرست منبع

provide emulation of fcntl F_DUPFD_CLOEXEC on old kernels

I'm not entirely happy with the amount of ugliness here, but since
F_DUPFD_CLOEXEC is used elsewhere in code that's expected to work on
old kernels (popen), it seems necessary. reportedly even some modern
kernels went back and broke F_DUPFD_CLOEXEC (making it behave like
plain F_DUPFD), so it might be necessary to add some additional fixup
code later to deal with that issue too.
Rich Felker 12 سال پیش
والد
کامیت
00f1521fdd
1فایلهای تغییر یافته به همراه16 افزوده شده و 0 حذف شده
  1. 16 0
      src/fcntl/fcntl.c

+ 16 - 0
src/fcntl/fcntl.c

@@ -22,5 +22,21 @@ int fcntl(int fd, int cmd, ...)
 		if (ret) return __syscall_ret(ret);
 		return ex.type == F_OWNER_PGRP ? -ex.pid : ex.pid;
 	}
+	if (cmd == F_DUPFD_CLOEXEC) {
+		int ret = __syscall(SYS_fcntl, fd, F_DUPFD_CLOEXEC, arg);
+		if (ret != -EINVAL) {
+			if (ret >= 0)
+				__syscall(SYS_fcntl, ret, F_SETFD, FD_CLOEXEC);
+			return __syscall_ret(ret);
+		}
+		ret = __syscall(SYS_fcntl, fd, F_DUPFD_CLOEXEC, 0);
+		if (ret != -EINVAL) {
+			if (ret >= 0) __syscall(SYS_close, ret);
+			return __syscall_ret(-EINVAL);
+		}
+		ret = __syscall(SYS_fcntl, fd, F_DUPFD, arg);
+		if (ret >= 0) __syscall(SYS_fcntl, ret, F_SETFD, FD_CLOEXEC);
+		return __syscall_ret(ret);
+	}
 	return syscall(SYS_fcntl, fd, cmd, arg);
 }