2 * setpgid.c -- execute a command in a new process group
3 * Daan De Meyer <daan.j.demeyer@gmail.com>
4 * In the public domain.
13 #include "closestream.h"
15 static void __attribute__((__noreturn__
)) usage(void)
18 fputs(USAGE_HEADER
, out
);
20 " %s [options] <program> [arguments ...]\n"),
21 program_invocation_short_name
);
23 fputs(USAGE_SEPARATOR
, out
);
24 fputs(_("Run a program in a new process group.\n"), out
);
26 fputs(USAGE_OPTIONS
, out
);
27 fputs(_(" -f, --foregound Make a foreground process group\n"), out
);
29 fprintf(out
, USAGE_HELP_OPTIONS(16));
31 fprintf(out
, USAGE_MAN_TAIL("setpgid(1)"));
35 int main(int argc
, char **argv
)
37 int ch
, foreground
= 0, fd
;
40 static const struct option longopts
[] = {
41 {"foreground", no_argument
, NULL
, 'f'},
42 {"version", no_argument
, NULL
, 'V'},
43 {"help", no_argument
, NULL
, 'h'},
47 setlocale(LC_ALL
, "");
48 bindtextdomain(PACKAGE
, LOCALEDIR
);
50 close_stdout_atexit();
52 while ((ch
= getopt_long(argc
, argv
, "+Vh", longopts
, NULL
)) != -1)
60 print_version(EXIT_SUCCESS
);
62 errtryhelp(EXIT_FAILURE
);
65 if (argc
- optind
< 1) {
66 warnx(_("no command specified"));
67 errtryhelp(EXIT_FAILURE
);
70 if (setpgid(0, 0) < 0)
71 err(EXIT_FAILURE
, _("setpgid failed"));
74 fd
= open("/dev/tty", O_RDONLY
|O_CLOEXEC
);
76 if (sigemptyset(&s
) < 0)
77 err(EXIT_FAILURE
, _("sigemptyset failed"));
78 if (sigaddset(&s
, SIGTTOU
) < 0)
79 err(EXIT_FAILURE
, _("sigaddset failed"));
80 if (sigprocmask(SIG_BLOCK
, &s
, &old
) < 0)
81 err(EXIT_FAILURE
, _("sigprocmask failed"));
82 if (tcsetpgrp(fd
, getpgid(0)) < 0)
83 err(EXIT_FAILURE
, _("tcsetpgrp failed"));
84 if (sigprocmask(SIG_SETMASK
, &old
, NULL
) < 0)
85 err(EXIT_FAILURE
, _("sigprocmask failed"));
89 execvp(argv
[optind
], argv
+ optind
);
90 errexec(argv
[optind
]);