fdflags -s was re-parsing the setspec for each fd argument. This is problematic because it is using strtok() to parse it destructively. So, only the first part of the setspec will be set for all file descriptors; the other parts will only be set for the first file descriptor:
$ enable fdflags $ exec {foo1}</dev/null {foo2}</dev/null $ fdflags -s +nonblock,+cloexec -- "$foo1" "$foo2" $ ls -ld /proc/self/fd/"$foo1" /proc/self/fd/"$foo2" ls: cannot access '/proc/self/fd/10': No such file or directory lr-x------ 1 emanuele6 wheel 64 Nov 5 14:45 /proc/self/fd/11 -> /dev/null $ fdflags -- "$foo1" "$foo2" 10:nonblock,cloexec 11:nonblock $ exec {foo1}<&- {foo2}<&- {foo3}</dev/null {foo4}</dev/null $ fdflags -s +cloexec,+nonblock -- "$foo3" "$foo4" $ fdflags -- "$foo3" "$foo4" 11:nonblock,cloexec 13:nonblock With this patch, the setspec string is only parsed once destructively, and then the parsed values are reused. That fixes the bug. --- examples/loadables/fdflags.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/examples/loadables/fdflags.c b/examples/loadables/fdflags.c index 48a1417f..d95b4815 100644 --- a/examples/loadables/fdflags.c +++ b/examples/loadables/fdflags.c @@ -224,16 +224,14 @@ parseflags(char *s, int *p, int *n) } static void -setone(int fd, char *v, int verbose) +setone(int fd, int pos, int neg, int verbose) { - int f, n, pos, neg, cloexec; + int f, n, cloexec; f = getflags(fd, 1); if (f == -1) return; - parseflags(v, &pos, &neg); - cloexec = -1; if ((pos & O_CLOEXEC) && (f & O_CLOEXEC) == 0) @@ -280,7 +278,7 @@ getmaxfd (void) int fdflags_builtin (WORD_LIST *list) { - int opt, maxfd, i, num, verbose, setflag; + int opt, maxfd, i, num, verbose, setflag, setpos, setneg; char *setspec; WORD_LIST *l; intmax_t inum; @@ -324,6 +322,9 @@ fdflags_builtin (WORD_LIST *list) return (EXECUTION_SUCCESS); } + if (setflag) + parseflags (setspec, &setpos, &setneg); + opt = EXECUTION_SUCCESS; for (l = list; l; l = l->next) { @@ -335,7 +336,7 @@ fdflags_builtin (WORD_LIST *list) } num = inum; /* truncate to int */ if (setflag) - setone (num, setspec, verbose); + setone (num, setpos, setneg, verbose); else printone (num, 1, verbose); } -- 2.42.0