about summary refs log tree commit diff
path: root/posix
diff options
context:
space:
mode:
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>2022-01-27 10:11:30 -0300
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>2022-02-02 08:34:16 -0300
commit6289d28d3c4e56f34830cfb011c31271ef850418 (patch)
tree32d0c4d7af2c5a6a9d293a1ea05eb0d45313e450 /posix
parent3f35e7d193b7ff098467996ebf85b19c41d6d86e (diff)
downloadglibc-6289d28d3c4e56f34830cfb011c31271ef850418.tar.gz
glibc-6289d28d3c4e56f34830cfb011c31271ef850418.tar.xz
glibc-6289d28d3c4e56f34830cfb011c31271ef850418.zip
posix: Replace posix_spawnattr_tc{get,set}pgrp_np with posix_spawn_file_actions_addtcsetpgrp_np
The posix_spawnattr_tcsetpgrp_np works on a file descriptor (the
controlling terminal), so it would make more sense to actually fit
it on the file actions API.

Also, POSIX_SPAWN_TCSETPGROUP is not really required since it is
implicit by the presence of tcsetpgrp file action.

The posix/tst-spawn6.c is also fixed when TTY can is not present.

Checked on x86_64-linux-gnu and i686-linux-gnu.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Tested-by: Carlos O'Donell <carlos@redhat.com>
Diffstat (limited to 'posix')
-rw-r--r--posix/Makefile2
-rw-r--r--posix/Versions3
-rw-r--r--posix/spawn.h24
-rw-r--r--posix/spawn_faction_addtcsetpgrp_np.c50
-rw-r--r--posix/spawn_faction_destroy.c1
-rw-r--r--posix/spawn_int.h5
-rw-r--r--posix/spawnattr_setflags.c3
-rw-r--r--posix/spawnattr_tcgetpgrp.c26
-rw-r--r--posix/spawnattr_tcsetpgrp.c26
-rw-r--r--posix/tst-spawn6.c83
10 files changed, 122 insertions, 101 deletions
diff --git a/posix/Makefile b/posix/Makefile
index 2b5b791374..9b30b53a7c 100644
--- a/posix/Makefile
+++ b/posix/Makefile
@@ -58,13 +58,13 @@ routines :=								      \
 	spawn_faction_addopen spawn_faction_adddup2 spawn_valid_fd	      \
 	spawn_faction_addchdir spawn_faction_addfchdir			      \
 	spawn_faction_addclosefrom					      \
+	spawn_faction_addtcsetpgrp_np					      \
 	spawnattr_init spawnattr_destroy				      \
 	spawnattr_getdefault spawnattr_setdefault			      \
 	spawnattr_getflags spawnattr_setflags				      \
 	spawnattr_getpgroup spawnattr_setpgroup spawn spawnp spawni	      \
 	spawnattr_getsigmask spawnattr_getschedpolicy spawnattr_getschedparam \
 	spawnattr_setsigmask spawnattr_setschedpolicy spawnattr_setschedparam \
-	spawnattr_tcgetpgrp spawnattr_tcsetpgrp				      \
 	posix_madvise							      \
 	get_child_max sched_cpucount sched_cpualloc sched_cpufree \
 	streams-compat \
diff --git a/posix/Versions b/posix/Versions
index e4f4f649b0..3753810864 100644
--- a/posix/Versions
+++ b/posix/Versions
@@ -157,8 +157,7 @@ libc {
     posix_spawn_file_actions_addclosefrom_np;
   }
   GLIBC_2.35 {
-    posix_spawnattr_tcgetpgrp_np;
-    posix_spawnattr_tcsetpgrp_np;
+    posix_spawn_file_actions_addtcsetpgrp_np;
   }
   GLIBC_PRIVATE {
     __libc_fork; __libc_pread; __libc_pwrite;
diff --git a/posix/spawn.h b/posix/spawn.h
index 7779020250..c4a81227b0 100644
--- a/posix/spawn.h
+++ b/posix/spawn.h
@@ -34,8 +34,7 @@ typedef struct
   sigset_t __ss;
   struct sched_param __sp;
   int __policy;
-  int __ctty_fd;
-  int __pad[15];
+  int __pad[16];
 } posix_spawnattr_t;
 
 
@@ -60,7 +59,6 @@ typedef struct
 #ifdef __USE_GNU
 # define POSIX_SPAWN_USEVFORK		0x40
 # define POSIX_SPAWN_SETSID		0x80
-# define POSIX_SPAWN_TCSETPGROUP	0x100
 #endif
 
 
@@ -168,19 +166,6 @@ extern int posix_spawnattr_setschedparam (posix_spawnattr_t *__restrict __attr,
 					  __restrict __schedparam)
      __THROW __nonnull ((1, 2));
 
-#ifdef __USE_GNU
-/* Make the spawned process the foreground process group on the terminal
-   associated with FD (which must be a controlling terminal, and still be
-   associated with its session).  */
-extern int posix_spawnattr_tcsetpgrp_np (posix_spawnattr_t *__attr, int fd)
-     __THROW __nonnull ((1));
-
-/* Return the associated terminal FD in the attribute structure.  */
-extern int posix_spawnattr_tcgetpgrp_np (const posix_spawnattr_t *
-					 __restrict __attr, int *fd)
-     __THROW __nonnull ((1, 2));
-#endif
-
 /* Initialize data structure for file attribute for `spawn' call.  */
 extern int posix_spawn_file_actions_init (posix_spawn_file_actions_t *
 					  __file_actions)
@@ -235,6 +220,13 @@ posix_spawn_file_actions_addclosefrom_np (posix_spawn_file_actions_t *,
 					  int __from)
      __THROW __nonnull ((1));
 
+/* Add an action to set the process group of the forground process group
+   associated with the terminal TCFD.  */
+extern int
+posix_spawn_file_actions_addtcsetpgrp_np (posix_spawn_file_actions_t *,
+					  int __tcfd)
+     __THROW __nonnull ((1));
+
 #endif
 
 __END_DECLS
diff --git a/posix/spawn_faction_addtcsetpgrp_np.c b/posix/spawn_faction_addtcsetpgrp_np.c
new file mode 100644
index 0000000000..86f882cd84
--- /dev/null
+++ b/posix/spawn_faction_addtcsetpgrp_np.c
@@ -0,0 +1,50 @@
+/* Add tcsetpgrp to the file action list for posix_spawn.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <spawn.h>
+#include <unistd.h>
+#include <spawn_int.h>
+
+int
+__posix_spawn_file_actions_addtcsetpgrp_np (posix_spawn_file_actions_t
+					    *file_actions, int tcfd)
+{
+  struct __spawn_action *rec;
+
+  if (!__spawn_valid_fd (tcfd))
+    return EBADF;
+
+  /* Allocate more memory if needed.  */
+  if (file_actions->__used == file_actions->__allocated
+      && __posix_spawn_file_actions_realloc (file_actions) != 0)
+    /* This can only mean we ran out of memory.  */
+    return ENOMEM;
+
+  /* Add the new value.  */
+  rec = &file_actions->__actions[file_actions->__used];
+  rec->tag = spawn_do_tcsetpgrp;
+  rec->action.setpgrp_action.fd = tcfd;
+
+  /* Account for the new entry.  */
+  ++file_actions->__used;
+
+  return 0;
+}
+weak_alias (__posix_spawn_file_actions_addtcsetpgrp_np,
+	    posix_spawn_file_actions_addtcsetpgrp_np)
diff --git a/posix/spawn_faction_destroy.c b/posix/spawn_faction_destroy.c
index eb5b727d34..add8799bb8 100644
--- a/posix/spawn_faction_destroy.c
+++ b/posix/spawn_faction_destroy.c
@@ -40,6 +40,7 @@ __posix_spawn_file_actions_destroy (posix_spawn_file_actions_t *file_actions)
 	case spawn_do_dup2:
 	case spawn_do_fchdir:
 	case spawn_do_closefrom:
+	case spawn_do_tcsetpgrp:
 	  /* No cleanup required.  */
 	  break;
 	}
diff --git a/posix/spawn_int.h b/posix/spawn_int.h
index f683db6217..f134d15b06 100644
--- a/posix/spawn_int.h
+++ b/posix/spawn_int.h
@@ -34,6 +34,7 @@ struct __spawn_action
     spawn_do_chdir,
     spawn_do_fchdir,
     spawn_do_closefrom,
+    spawn_do_tcsetpgrp
   } tag;
 
   union
@@ -66,6 +67,10 @@ struct __spawn_action
     {
       int from;
     } closefrom_action;
+    struct
+    {
+      int fd;
+    } setpgrp_action;
   } action;
 };
 
diff --git a/posix/spawnattr_setflags.c b/posix/spawnattr_setflags.c
index 603bfcf911..3e6fe4ef03 100644
--- a/posix/spawnattr_setflags.c
+++ b/posix/spawnattr_setflags.c
@@ -26,8 +26,7 @@
 		   | POSIX_SPAWN_SETSCHEDPARAM				      \
 		   | POSIX_SPAWN_SETSCHEDULER				      \
 		   | POSIX_SPAWN_SETSID					      \
-		   | POSIX_SPAWN_USEVFORK				      \
-		   | POSIX_SPAWN_TCSETPGROUP)
+		   | POSIX_SPAWN_USEVFORK)
 
 /* Store flags in the attribute structure.  */
 int
diff --git a/posix/spawnattr_tcgetpgrp.c b/posix/spawnattr_tcgetpgrp.c
deleted file mode 100644
index 8db33e4474..0000000000
--- a/posix/spawnattr_tcgetpgrp.c
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Get the controlling terminal option.
-   Copyright (C) 2022 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <https://www.gnu.org/licenses/>.  */
-
-#include <spawn.h>
-
-int
-posix_spawnattr_tcgetpgrp_np (const posix_spawnattr_t *attr, int *fd)
-{
-  *fd = attr->__ctty_fd;
-  return 0;
-}
diff --git a/posix/spawnattr_tcsetpgrp.c b/posix/spawnattr_tcsetpgrp.c
deleted file mode 100644
index c3b2ea2718..0000000000
--- a/posix/spawnattr_tcsetpgrp.c
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Set the controlling terminal option.
-   Copyright (C) 2022 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <https://www.gnu.org/licenses/>.  */
-
-#include <spawn.h>
-
-int
-posix_spawnattr_tcsetpgrp_np (posix_spawnattr_t *attr, int fd)
-{
-  attr->__ctty_fd = fd;
-  return 0;
-}
diff --git a/posix/tst-spawn6.c b/posix/tst-spawn6.c
index 5f95bd1938..911e90a461 100644
--- a/posix/tst-spawn6.c
+++ b/posix/tst-spawn6.c
@@ -29,12 +29,11 @@
 #include <support/check.h>
 #include <support/xunistd.h>
 #include <sys/wait.h>
+#include <stdlib.h>
 
 static int
-handle_restart (const char *argv1)
+handle_restart (const char *argv1, const char *argv2)
 {
-  int fd = xopen (_PATH_TTY, O_RDONLY, 0600);
-
   /* If process group is not changed (POSIX_SPAWN_SETPGROUP), then check
      the creating process one, otherwise check against the process group
      itself.  */
@@ -50,9 +49,20 @@ handle_restart (const char *argv1)
       TEST_VERIFY (pgid != pgrp);
     }
 
-  TEST_COMPARE (tcgetpgrp (fd), pgrp);
+  char *endptr;
+  long int tcfd = strtol (argv2, &endptr, 10);
+  if (*endptr != '\0' || tcfd > INT_MAX)
+    FAIL_EXIT1 ("invalid file descriptor name: %s", argv2);
+  if (tcfd != -1)
+    {
+      TEST_COMPARE (fcntl (tcfd, F_GETFD), -1);
+      TEST_COMPARE (errno, EBADF);
+    }
 
+  int fd = xopen (_PATH_TTY, O_RDONLY, 0600);
+  TEST_COMPARE (tcgetpgrp (fd), pgrp);
   xclose (fd);
+
   return 0;
 }
 
@@ -62,6 +72,7 @@ static int restart;
 
 static void
 run_subprogram (int argc, char *argv[], const posix_spawnattr_t *attr,
+		const posix_spawn_file_actions_t *actions, int tcfd,
 		int exp_err)
 {
   short int flags;
@@ -69,7 +80,9 @@ run_subprogram (int argc, char *argv[], const posix_spawnattr_t *attr,
   bool setpgrp = flags & POSIX_SPAWN_SETPGROUP;
 
   char *spargv[9];
+  TEST_VERIFY_EXIT (((argc - 1) + 4) < array_length (spargv));
   char pgrp[INT_STRLEN_BOUND (pid_t)];
+  char tcfdstr[INT_STRLEN_BOUND (int)];
 
   int i = 0;
   for (; i < argc - 1; i++)
@@ -83,11 +96,12 @@ run_subprogram (int argc, char *argv[], const posix_spawnattr_t *attr,
       snprintf (pgrp, sizeof pgrp, "%d", getpgrp ());
       spargv[i++] = pgrp;
     }
+  snprintf (tcfdstr, sizeof tcfdstr, "%d", tcfd);
+  spargv[i++] = tcfdstr;
   spargv[i] = NULL;
-  TEST_VERIFY_EXIT (i < array_length (spargv));
 
   pid_t pid;
-  TEST_COMPARE (posix_spawn (&pid, argv[1], NULL, attr, spargv, environ),
+  TEST_COMPARE (posix_spawn (&pid, argv[1], actions, attr, spargv, environ),
 		exp_err);
   if (exp_err != 0)
     return;
@@ -114,44 +128,55 @@ do_test (int argc, char *argv[])
    */
 
   if (restart)
-    return handle_restart (argv[1]);
+    return handle_restart (argv[1], argv[2]);
 
-  int tcfd = xopen (_PATH_TTY, O_RDONLY, 0600);
+  int tcfd = open64 (_PATH_TTY, O_RDONLY, 0600);
+  if (tcfd == -1)
+    {
+      if (errno == ENXIO)
+	FAIL_UNSUPPORTED ("terminal not available, skipping test");
+      FAIL_EXIT1 ("open64 (\"%s\", 0x%x, 0600): %m", _PATH_TTY, O_RDONLY);
+    }
 
-  /* Check getters and setters.  */
+  /* Check setting the controlling terminal without changing the group.  */
   {
     posix_spawnattr_t attr;
     TEST_COMPARE (posix_spawnattr_init (&attr), 0);
-    TEST_COMPARE (posix_spawnattr_tcsetpgrp_np (&attr, tcfd), 0);
+    posix_spawn_file_actions_t actions;
+    TEST_COMPARE (posix_spawn_file_actions_init (&actions), 0);
+    TEST_COMPARE (posix_spawn_file_actions_addtcsetpgrp_np (&actions, tcfd),
+		  0);
 
-    int fd;
-    TEST_COMPARE (posix_spawnattr_tcgetpgrp_np (&attr, &fd), 0);
-    TEST_COMPARE (tcfd, fd);
+    run_subprogram (argc, argv, &attr, &actions, -1, 0);
   }
 
-  /* Check setting the controlling terminal without changing the group.  */
+  /* Check setting both the controlling terminal and the create a new process
+     group.  */
   {
     posix_spawnattr_t attr;
     TEST_COMPARE (posix_spawnattr_init (&attr), 0);
-    TEST_COMPARE (posix_spawnattr_setflags (&attr, POSIX_SPAWN_TCSETPGROUP),
+    TEST_COMPARE (posix_spawnattr_setflags (&attr, POSIX_SPAWN_SETPGROUP), 0);
+    posix_spawn_file_actions_t actions;
+    TEST_COMPARE (posix_spawn_file_actions_init (&actions), 0);
+    TEST_COMPARE (posix_spawn_file_actions_addtcsetpgrp_np (&actions, tcfd),
 		  0);
-    TEST_COMPARE (posix_spawnattr_tcsetpgrp_np (&attr, tcfd), 0);
 
-    run_subprogram (argc, argv, &attr, 0);
+    run_subprogram (argc, argv, &attr, &actions, -1, 0);
   }
 
-  /* Check setting both the controlling terminal and the create a new process
-     group.  */
+  /* Same as before, but check if the addclose file actions closes the terminal
+     file descriptor.  */
   {
     posix_spawnattr_t attr;
     TEST_COMPARE (posix_spawnattr_init (&attr), 0);
-    TEST_COMPARE (posix_spawnattr_setflags (&attr, POSIX_SPAWN_TCSETPGROUP
-						   | POSIX_SPAWN_SETPGROUP),
+    TEST_COMPARE (posix_spawnattr_setflags (&attr, POSIX_SPAWN_SETPGROUP), 0);
+    posix_spawn_file_actions_t actions;
+    TEST_COMPARE (posix_spawn_file_actions_init (&actions), 0);
+    TEST_COMPARE (posix_spawn_file_actions_addtcsetpgrp_np (&actions, tcfd),
 		  0);
-    TEST_COMPARE (posix_spawnattr_setpgroup (&attr, 0), 0);
-    TEST_COMPARE (posix_spawnattr_tcsetpgrp_np (&attr, tcfd), 0);
+    TEST_COMPARE (posix_spawn_file_actions_addclose (&actions, tcfd), 0);
 
-    run_subprogram (argc, argv, &attr, 0);
+    run_subprogram (argc, argv, &attr, &actions, tcfd, 0);
   }
 
   /* Trying to set the controlling terminal after a setsid incurs in a ENOTTY
@@ -159,11 +184,13 @@ do_test (int argc, char *argv[])
   {
     posix_spawnattr_t attr;
     TEST_COMPARE (posix_spawnattr_init (&attr), 0);
-    TEST_COMPARE (posix_spawnattr_setflags (&attr, POSIX_SPAWN_TCSETPGROUP
-						   | POSIX_SPAWN_SETSID), 0);
-    TEST_COMPARE (posix_spawnattr_tcsetpgrp_np (&attr, tcfd), 0);
+    TEST_COMPARE (posix_spawnattr_setflags (&attr, POSIX_SPAWN_SETSID), 0);
+    posix_spawn_file_actions_t actions;
+    TEST_COMPARE (posix_spawn_file_actions_init (&actions), 0);
+    TEST_COMPARE (posix_spawn_file_actions_addtcsetpgrp_np (&actions, tcfd),
+		  0);
 
-    run_subprogram (argc, argv, &attr, ENOTTY);
+    run_subprogram (argc, argv, &attr, &actions, -1, ENOTTY);
   }
 
   xclose (tcfd);