supporting terminal ownership assignment (tcsetpgrp()) in posix_spawn

Adhemerval Zanella adhemerval.zanella@linaro.org
Fri Jun 11 13:45:47 GMT 2021



On 09/06/2021 10:12, Godmar Back wrote:
> On Wed, Jun 9, 2021 at 8:00 AM Adhemerval Zanella <
> adhemerval.zanella@linaro.org> wrote:
> 
>>
>> The libc interface should be as generic possible to cover most users cases,
>> I really don't want to add a posix_spawnattr_tcsetpgrp_np that uses the
>> groupid implicit from POSIX_SPAWN_SETPGROUP to someone ask for a
>> posix_spawnattr_tcsetpgrp_np_ex so one can set the groupid.
>>
>> Also, requiring POSIX_SPAWN_SETPGROUP for posix_spawnattr_tcsetpgrp_np is
>> not really a good API, it adds subtle semantics (should it use a default
>> value set by posix_spawnattr_init or should we fail with EINVAL), and adds
>> complexity in the error path (we will need to either pre validate the
>> posix_spawnattr_t input before start the process creation or handle a
>> possible invalid combination on the helper process itself).
>>
>> That's why I am more inclined to follow the tcsetpgrp on the posix_spawn
>> extension and let the caller set the required groups.
>>
>>
> I just checked and I don't think this will even work.  The caller cannot
> provide the process group id because the caller can't know it yet.
> A typical sequence in the first child of a pipeline is "setpgid(0, 0);
> tcsetpgrp(fd, getpgrp());" and AFAIK tcsetpgrp doesn't accept '0' to stand
> for the
> current process's process group.

Indeed I think it wouldn't make sense to provide the input process group
argument, in only does if the created process wants to become de process
 group leader (POSIX_SPAWN_SETPGROUP plus posix_spawnattr_setpgroup (0)).

However I don't think adding a flag as QNX does (POSIX_SPAWN_TCSETPGROUP) 
is the best approach: it requires posix_spawn opening a new file descriptor 
to obtain the controlling terminal.  It add extra error path and put pressure
on the total file descriptor process has (assuming that caller expects no
file operation is done by posix_spawn).

So maybe this following:

  int posix_spawnattr_tcsetpgrp_np (posix_spawnattr_t *__attr, int fd);

  Similar to tcgetpgrp, it make the process group of the created process the
  foreground process group on the terminal associated to FD.  It is similar
  to tcsetpgrp(), where FD must be controlling terminal of the calling process,
  and still be associated with its session.

  It can be used along with POSIX_SPAWN_SETPGROUP to make the created process
  a new group leader to be used as the process group.


And then you can make a new process the foreground process group with:

  int fd = open (_PATH_TTY, O_RDWR | O_CLOEXEC);
  
  posix_spawnattr_t attr;
  posix_spawnattr_init (&attr);
  posix_spawnattr_setflags (&attr, POSIX_SPAWN_SETPGROUP)
  posix_spawnattr_tcsetpgrp_np (&attr, fd);

  pid_t pid;
  char *args[] = { NULL };
  posix_spawn (&pid, "/path/to/program", NULL, &attr, args, NULL);





More information about the Libc-help mailing list