Skip to content

Commit eacfddf

Browse files
authored
Avoid setErrno dependency in __syscall_fcntl64. NFC (#21064)
From the manpage for fcntl: ``` F_GETOWN A limitation of the Linux system call conventions on some architectures (notably i386) means that if a (negative) process group ID to be returned by F_GETOWN falls in the range -1 to -4095, then the return value is wrongly interpreted by glibc as an error in the system call; that is, the return value of fcntl() will be -1, and errno will contain the (positive) process group ID. The Linux-spe‐ cific F_GETOWN_EX operation avoids this problem. Since glibc 2.11, glibc makes the kernel F_GETOWN problem invisible by implementing F_GETOWN using F_GETOWN_EX. ```
1 parent 027ace3 commit eacfddf

File tree

3 files changed

+11
-19
lines changed

3 files changed

+11
-19
lines changed

src/library_syscall.js

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -758,7 +758,6 @@ var SyscallsLibrary = {
758758
FS.llseek(stream, idx * struct_size, {{{ cDefs.SEEK_SET }}});
759759
return pos;
760760
},
761-
__syscall_fcntl64__deps: ['$setErrNo'],
762761
__syscall_fcntl64: (fd, cmd, varargs) => {
763762
#if SYSCALLS_REQUIRE_FILESYSTEM == 0
764763
#if SYSCALL_DEBUG
@@ -800,20 +799,16 @@ var SyscallsLibrary = {
800799
case {{{ cDefs.F_SETLK }}}:
801800
case {{{ cDefs.F_SETLKW }}}:
802801
return 0; // Pretend that the locking is successful.
802+
#if SYSCALL_DEBUG
803803
case {{{ cDefs.F_GETOWN_EX }}}:
804804
case {{{ cDefs.F_SETOWN }}}:
805-
return -{{{ cDefs.EINVAL }}}; // These are for sockets. We don't have them fully implemented yet.
806805
case {{{ cDefs.F_GETOWN }}}:
807-
// musl trusts getown return values, due to a bug where they must be, as they overlap with errors. just return -1 here, so fcntl() returns that, and we set errno ourselves.
808-
setErrNo({{{ cDefs.EINVAL }}});
809-
return -1;
810-
default: {
811-
#if SYSCALL_DEBUG
806+
return -{{{ cDefs.EINVAL }}};
807+
default:
812808
dbg(`warning: fcntl unrecognized command ${cmd}`);
813809
#endif
814-
return -{{{ cDefs.EINVAL }}};
815-
}
816810
}
811+
return -{{{ cDefs.EINVAL }}};
817812
#endif // SYSCALLS_REQUIRE_FILESYSTEM
818813
},
819814

system/lib/libc/musl/src/fcntl/fcntl.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,14 @@ int fcntl(int fd, int cmd, ...)
2424
if (cmd == F_GETOWN) {
2525
struct f_owner_ex ex;
2626
int ret = __syscall(SYS_fcntl, fd, F_GETOWN_EX, &ex);
27+
#ifdef __EMSCRIPTEN__
28+
// XXX Emscripten: Mirror the behaviour/limitation of glibc which
29+
// will misinterpret negative PIDs in range of -1 to -4095 as being
30+
// errno values.
31+
if (ret == -EINVAL) ret = __syscall(SYS_fcntl, fd, cmd, (void *)arg);
32+
#else
2733
if (ret == -EINVAL) return __syscall(SYS_fcntl, fd, cmd, (void *)arg);
34+
#endif
2835
if (ret) return __syscall_ret(ret);
2936
return ex.type == F_OWNER_PGRP ? -ex.pid : ex.pid;
3037
}

system/lib/wasmfs/syscalls.cpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1525,16 +1525,6 @@ int __syscall_fcntl64(int fd, int cmd, ...) {
15251525
// Always error for now, until we implement byte-range locks.
15261526
return -EACCES;
15271527
}
1528-
case F_GETOWN_EX:
1529-
case F_SETOWN:
1530-
// These are for sockets. We don't have them fully implemented yet.
1531-
return -EINVAL;
1532-
case F_GETOWN:
1533-
// Work around what seems to be a musl bug, where they do not set errno
1534-
// in the caller. This has been an issue since the JS filesystem and had
1535-
// the same workaround there.
1536-
errno = EINVAL;
1537-
return -1;
15381528
default: {
15391529
// TODO: support any remaining cmds
15401530
return -EINVAL;

0 commit comments

Comments
 (0)