Search code examples
cttyctrltermcap

Why can't I retrieve my program that was suspended from inside backticks?


I created a program that takes a list of arguments and put them in a grid on a new tty where I can move around and select from it what I want.

When I run the program without backticks like this...

$> ./ft_select arg_1 arg_2 ... arg_N

A new tty is opened and a grid is shown...

arg_1  arg_2  arg_3
arg_4  arg_5  arg_6
arg_7  ...    arg_N

I hit ctrl+z and the program gets suspended with no problem and fg command puts it back.

My problem is that when I put the command between backticks and I try to suspend it, it get stuck without giving the prompt back.

I have to mention that I write all the content of the grid on /dev/tty

You can find in the code below the function that does the signal handling.

 23 void    signalhandler(int sig)
 24 {
 25 //  struct winsize  ws;
 26
 27     if (sig == SIGWINCH)
 28     {
 29 //      ioctl(g_data->tty, TIOCGWINSZ, &ws);
 30         update_data(g_data);
 31         print_args(g_data);
 32         update_cursor(g_data, 1);
 33     }
 34     else if (sig == SIGTSTP)
 35     {
 36         signal(SIGTSTP, SIG_DFL);
 37         enable_cap("te");
 38         modify_main_caps(SET, g_data->tty);
 39         ioctl(g_data->tty, TIOCSTI, "\032");
 40     }
 41     else if (sig == SIGCONT)
 42     {
 43         signal(SIGTSTP, signalhandler);
 44         modify_main_caps(UNSET, g_data->tty);
 45         update_data(g_data);
 46         print_args(g_data);
 47         update_cursor(g_data, 1);
 48     }
 49     else if (sig == SIGINT)
 50     {
 51         enable_cap("te");
 52         modify_main_caps(SET, g_data->tty);
 53         exit(EXIT_FAILURE);
 54     }
 55 }

Solution

  • CTRL+Z causes the terminal device driver to send a SIGTSTP to all processes in the foreground process group. In bash and zsh, at least, commands in a command substitution $(<command>) are executed in a subshell, but they don't get their own process group (they run in the same process group as the parent shell itself). That means that CTRL+Z should not affect them at all - press it and nothing happens, just like pressing CTRL+Z in a shell prompt doesn't do anything: in both cases, there is no foreground process group to suspend!