Skip to content

Commit 9fa1f58

Browse files
author
magicant
committed
yash: ジョブ制御有効時にシェルの pgid を変更するのをやめた
yash: -initial_pgid, set_own_pgid, reset_own_pgid, forget_initial_pgid, yash: -finalize_shell, reinitialize_shell yash: シェル起動時にシェル自身がフォアグラウンドにいるか確認するように job: +ensure_foreground git-svn-id: svn+ssh://svn.sourceforge.jp/svnroot/yash/yash/trunk@1324 048f04df-13f5-43d7-8114-9f9ceecaec24
1 parent 9308033 commit 9fa1f58

8 files changed

Lines changed: 52 additions & 75 deletions

File tree

exec.c

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -813,8 +813,7 @@ pid_t fork_and_reset(pid_t pgid, bool fg, sigtype_T sigtype)
813813
if (sigblock) {
814814
sigfillset(&all);
815815
sigemptyset(&savemask);
816-
if (sigprocmask(SIG_BLOCK, &all, &savemask) < 0)
817-
xerror(errno, "sigprocmask"), sigblock = false;
816+
sigprocmask(SIG_BLOCK, &all, &savemask);
818817
}
819818

820819
pid_t cpid = fork();
@@ -840,7 +839,6 @@ pid_t fork_and_reset(pid_t pgid, bool fg, sigtype_T sigtype)
840839
put_foreground(pgid);
841840
}
842841
}
843-
forget_initial_pgid();
844842
neglect_all_jobs();
845843
restore_job_signals();
846844
restore_interactive_signals();
@@ -859,8 +857,7 @@ pid_t fork_and_reset(pid_t pgid, bool fg, sigtype_T sigtype)
859857
ignore_sigtstp();
860858
}
861859
if (sigblock)
862-
if (sigprocmask(SIG_SETMASK, &savemask, NULL) < 0)
863-
xerror(errno, "sigprocmask");
860+
sigprocmask(SIG_SETMASK, &savemask, NULL);
864861
return cpid;
865862
}
866863

@@ -1777,7 +1774,6 @@ int exec_builtin_2(int argc, void **argv, const wchar_t *as, bool clear)
17771774
}
17781775
}
17791776

1780-
finalize_shell();
17811777
restore_all_signals();
17821778
xexecve(commandpath, args, envs ? envs : environ);
17831779
if (errno != ENOEXEC) {
@@ -1795,7 +1791,6 @@ int exec_builtin_2(int argc, void **argv, const wchar_t *as, bool clear)
17951791
exit(Exit_NOEXEC);
17961792
init_signal();
17971793
set_signals();
1798-
reinitialize_shell();
17991794
err = Exit_NOEXEC;
18001795

18011796
recfree((void **) envs, free);

job.c

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,6 @@ int send_signal_to_job(int signum, const wchar_t *jobname)
450450
* true. */
451451
void put_foreground(pid_t pgrp)
452452
{
453-
bool saveok;
454453
sigset_t blockss, savess;
455454

456455
assert(doing_job_control_now);
@@ -459,12 +458,43 @@ void put_foreground(pid_t pgrp)
459458
sigemptyset(&blockss);
460459
sigaddset(&blockss, SIGTTOU);
461460
sigemptyset(&savess);
462-
saveok = sigprocmask(SIG_BLOCK, &blockss, &savess) >= 0;
461+
sigprocmask(SIG_BLOCK, &blockss, &savess);
463462

464463
tcsetpgrp(ttyfd, pgrp);
465464

466-
if (saveok)
467-
sigprocmask(SIG_SETMASK, &savess, NULL);
465+
sigprocmask(SIG_SETMASK, &savess, NULL);
466+
}
467+
468+
/* Ensures the current shell process is in the foreground.
469+
* The shell process is stopped by SIGTTOU until it is put in the foreground.
470+
* This function requires `doing_job_control_now' to be true. */
471+
void ensure_foreground(void)
472+
{
473+
/* This function calls `tcsetpgrp' with the default SIGTTOU handler. If the
474+
* shell is in the background, it will receive SIGTTOU and is stopped until
475+
* continued in the foreground. */
476+
477+
struct sigaction dflsa, savesa;
478+
sigset_t blockss, savess;
479+
480+
assert(doing_job_control_now);
481+
assert(shell_pgid > 0);
482+
483+
dflsa.sa_handler = SIG_DFL;
484+
dflsa.sa_flags = 0;
485+
sigemptyset(&dflsa.sa_mask);
486+
sigemptyset(&savesa.sa_mask);
487+
sigaction(SIGTTOU, &dflsa, &savesa);
488+
489+
sigemptyset(&blockss);
490+
sigaddset(&blockss, SIGTTOU);
491+
sigemptyset(&savess);
492+
sigprocmask(SIG_UNBLOCK, &blockss, &savess);
493+
494+
tcsetpgrp(ttyfd, shell_pgid);
495+
496+
sigprocmask(SIG_SETMASK, &savess, NULL);
497+
sigaction(SIGTTOU, &savesa, NULL);
468498
}
469499

470500
/* Computes the exit status from the status code returned by `waitpid'. */

job.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ extern int send_signal_to_job(int signum, const wchar_t *jobname)
8585
__attribute__((nonnull));
8686

8787
extern void put_foreground(pid_t pgrp);
88+
extern void ensure_foreground(void);
8889

8990
extern int calc_status_of_job(const job_T *job)
9091
__attribute__((pure,nonnull));

option.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#endif
3030
#include "builtin.h"
3131
#include "exec.h"
32+
#include "job.h"
3233
#include "option.h"
3334
#include "redir.h"
3435
#include "sig.h"
@@ -325,12 +326,12 @@ void set_monitor_option(void *argp __attribute__((unused)))
325326
do_job_control = newvalue;
326327
} else {
327328
if (newvalue != do_job_control) {
328-
reset_own_pgid();
329329
do_job_control = newvalue;
330330
if (newvalue && ttyfd < 0)
331331
open_ttyfd();
332332
set_signals();
333-
set_own_pgid();
333+
if (do_job_control)
334+
ensure_foreground();
334335
}
335336
}
336337
/* When `shell_pid' is zero, the shell is under initialization;

tests/builtin.y.out

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ type: cd: no such command or function
9292
===== suspend =====
9393
1
9494
STOP
95+
TTOU
9596
2
9697
end
9798
===== exec =====

tests/builtin.y.tst

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,10 @@ PATH= type -B cd 2>&1
107107
echo ===== suspend =====
108108

109109
set -m
110-
($INVOKE $TESTEE -imc --norc 'echo 1; suspend; echo 2'; echo end)&
111-
wait $!
110+
($INVOKE $TESTEE -imc --norc 'echo 1; suspend; echo 2'; echo end)
111+
kill -l $?
112+
bg >/dev/null
113+
wait %1
112114
kill -l $?
113115
fg >/dev/null
114116
set +m

yash.c

Lines changed: 7 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,7 @@ static bool input_is_interactive_terminal(const parseinfo_T *pinfo)
6363

6464
/* the process ID of the shell */
6565
pid_t shell_pid;
66-
/* the initial/current process group ID of the shell */
67-
static pid_t initial_pgid;
66+
/* the process group ID of the shell */
6867
pid_t shell_pgid;
6968

7069
/* an equivalent to the -f flag for "exit" builtin */
@@ -209,7 +208,7 @@ int main(int argc, char **argv)
209208
/* `shell_pid' must be initialized after the options have been parsed.
210209
* This is required for the `set_monitor_option' function to work. */
211210
shell_pid = getpid();
212-
initial_pgid = shell_pgid = getpgrp();
211+
shell_pgid = getpgrp();
213212
init_cmdhash();
214213
init_homedirhash();
215214
init_variables();
@@ -273,7 +272,8 @@ int main(int argc, char **argv)
273272
if (is_interactive || do_job_control)
274273
open_ttyfd();
275274
set_signals();
276-
set_own_pgid();
275+
if (do_job_control)
276+
ensure_foreground();
277277
set_positional_parameters(wargv + xoptind);
278278
if (getuid() == geteuid() && getgid() == getegid()) {
279279
if (!noprofile)
@@ -370,23 +370,9 @@ void exit_shell_with_status(int status)
370370
finalize_history();
371371
#endif
372372
}
373-
finalize_shell();
374373
exit(exitstatus);
375374
}
376375

377-
/* Does what to do before exiting/suspending the shell.
378-
* The EXIT trap should be executed beforehand if needed. */
379-
void finalize_shell(void)
380-
{
381-
reset_own_pgid();
382-
}
383-
384-
/* Cancels `finalize_shell'. */
385-
void reinitialize_shell(void)
386-
{
387-
set_own_pgid();
388-
}
389-
390376
/* Prints the help message to stdout */
391377
void print_help(void)
392378
{
@@ -456,39 +442,6 @@ void print_version(void)
456442
}
457443

458444

459-
/* If job control is active, sets the process group ID of the shell to its
460-
* process ID. */
461-
void set_own_pgid(void)
462-
{
463-
if (doing_job_control_now && initial_pgid > 0 && shell_pgid != shell_pid) {
464-
if (setpgid(0, 0) == 0) {
465-
shell_pgid = shell_pid;
466-
put_foreground(shell_pgid);
467-
}
468-
}
469-
}
470-
471-
/* If job control is active, resets the process group ID of the shell.
472-
* The initial process group ID is restored. */
473-
void reset_own_pgid(void)
474-
{
475-
if (doing_job_control_now && initial_pgid > 0
476-
&& initial_pgid != shell_pgid) {
477-
if (setpgid(0, initial_pgid) == 0) {
478-
shell_pgid = initial_pgid;
479-
put_foreground(shell_pgid);
480-
}
481-
}
482-
}
483-
484-
/* Forgets the value of `initial_pgid' so that `reset_own_pgid' is no longer
485-
* effective. */
486-
void forget_initial_pgid(void)
487-
{
488-
initial_pgid = 0;
489-
}
490-
491-
492445
/********** Functions to execute commands **********/
493446

494447
/* Parses a multibyte string and executes the commands.
@@ -746,19 +699,19 @@ int suspend_builtin(int argc, void **argv)
746699
}
747700
if (argc != xoptind)
748701
goto print_usage;
749-
if (!force && is_interactive_now && getsid(0) == initial_pgid) {
702+
if (!force && is_interactive_now && getsid(0) == shell_pgid) {
750703
xerror(0, Ngt("refusing to suspend because of possible deadlock.\n"
751704
"Use the -f option to suspend anyway."));
752705
return Exit_FAILURE;
753706
}
754707

755708
bool ok;
756709

757-
finalize_shell();
758710
ok = send_sigstop_to_myself();
759711
if (!ok)
760712
xerror(errno, Ngt("cannot send SIGSTOP signal"));
761-
reinitialize_shell();
713+
if (doing_job_control_now)
714+
ensure_foreground();
762715
return ok ? Exit_SUCCESS : Exit_FAILURE;
763716
}
764717

yash.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,6 @@
2525

2626
extern pid_t shell_pid, shell_pgid;
2727

28-
extern void finalize_shell(void);
29-
extern void reinitialize_shell(void);
30-
extern void set_own_pgid(void);
31-
extern void reset_own_pgid(void);
32-
extern void forget_initial_pgid(void);
33-
3428
static inline void exit_shell(void)
3529
__attribute__((noreturn));
3630
extern void exit_shell_with_status(int status)

0 commit comments

Comments
 (0)