Skip to content

Commit

Permalink
[fg] track master proc for suspend via pids, not term fds, for fork_o…
Browse files Browse the repository at this point in the history
…n_start

When ui.sessions.fork_on_start, we fork a process that has a different
fdout than get_output_handle() (which has hardcoded fdout of 1), so it
will never be considered term->master, yet this is the process we want
to wake up in SIGTSTP handler.

Since we cannot rely on term->master to determine if we are the master
process, we instead move master_pid to be set explicitly at the places
where we have information about whether our process is a master or a
slave: first on start, then once the interlink determination has been
made.

master_pid has to be set in both parent and child, because both will get
suspended and need to know which one needs to resume in background with
SIGCONT (the master).  We can't inherit from the parent because it's
unknown at the time of fork.

Previously, master_pid worked correctly with fork_on_start=0,
-no-connect or -dump, but not with fork_on_start=1.

See #287 for background.
  • Loading branch information
smemsh committed Apr 10, 2024
1 parent 5886cad commit b2556aa
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 11 deletions.
13 changes: 11 additions & 2 deletions src/main/interlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -518,13 +518,15 @@ int
init_interlink(void)
{
int fd = connect_to_af_unix();
int pid;

if (fd != -1 || remote_session_flags) return fd;

parse_options_again();

if (get_opt_bool("ui.sessions.fork_on_start", NULL)) {

pid_t pid;

pid = fork();

if (pid == -1) return -1;
Expand All @@ -535,11 +537,18 @@ init_interlink(void)
for (i = 1; i <= (MAX_BIND_TRIES+2); ++i) {
fd = connect_to_af_unix();

if (fd != -1) return fd;
if (fd != -1) {
master_pid = pid;
return fd;
}
elinks_usleep(BIND_TRIES_DELAY * i);
}
return -1;
}
/* child */
#ifdef HAVE_GETPID
master_pid = getpid();
#endif
close_terminal_pipes();
}
bind_to_af_unix();
Expand Down
5 changes: 5 additions & 0 deletions src/main/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@

struct program program;

pid_t master_pid = 0;

static int ac;
static char **av;
static int init_b = 0;
Expand Down Expand Up @@ -193,6 +195,9 @@ init(void)
|| get_cmd_opt_bool("source")
|| (fd = init_interlink()) == -1) {

#ifdef HAVE_GETPID
master_pid = getpid();
#endif
parse_options_again();
init_b = 1;
init_modules(builtin_modules);
Expand Down
1 change: 1 addition & 0 deletions src/main/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ struct program {
};

extern struct program program;
extern pid_t master_pid;

void shrink_memory(int);
void parse_options_again(void);
Expand Down
2 changes: 1 addition & 1 deletion src/osdep/signals.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ sig_tstp(struct terminal *term)

block_itrm();
#if defined (SIGCONT) && defined(SIGTTOU)
if (master_pid) {
if (pid == master_pid) {
pid_t newpid = fork();
if (!newpid) {
int r;
Expand Down
8 changes: 0 additions & 8 deletions src/terminal/terminal.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,6 @@ INIT_LIST_OF(struct terminal, terminals);
struct hash *temporary_files;
static void check_if_no_terminal(void);

pid_t master_pid = 0;

void
clean_temporary_files(void)
{
Expand Down Expand Up @@ -191,12 +189,6 @@ init_term(int fdin, int fdout)
term->fdout = fdout;
term->master = (term->fdout == get_output_handle());

#ifdef HAVE_GETPID
if (term->master) {
master_pid = getpid();
}
#endif

term->blocked = -1;

get_terminal_name(name + 9);
Expand Down

0 comments on commit b2556aa

Please sign in to comment.