bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] fdflags: fix -s with multiple flags, and multiple fd arguments


From: Emanuele Torre
Subject: [PATCH] fdflags: fix -s with multiple flags, and multiple fd arguments
Date: Sun, 5 Nov 2023 14:51:12 +0100

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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]