source: MondoRescue/branches/3.3/mindi-busybox/miscutils/setsid.c@ 3865

Last change on this file since 3865 was 3621, checked in by Bruno Cornec, 10 years ago

New 3?3 banch for incorporation of latest busybox 1.25. Changing minor version to handle potential incompatibilities.

File size: 2.1 KB
RevLine 
[821]1/* vi: set sw=4 ts=4: */
2/*
3 * setsid.c -- execute a command in a new session
4 * Rick Sladkey <jrs@world.std.com>
5 * In the public domain.
6 *
[2725]7 * 1999-02-22 Arkadiusz Mickiewicz <misiek@pld.ORG.PL>
[821]8 * - added Native Language Support
9 *
10 * 2001-01-18 John Fremlin <vii@penguinpowered.com>
11 * - fork in case we are process group leader
12 *
13 * 2004-11-12 Paul Fox
14 * - busyboxed
15 */
16
[3232]17//usage:#define setsid_trivial_usage
[3621]18//usage: "[-c] PROG ARGS"
[3232]19//usage:#define setsid_full_usage "\n\n"
20//usage: "Run PROG in a new session. PROG will have no controlling terminal\n"
[3621]21//usage: "and will not be affected by keyboard signals (^C etc).\n"
22//usage: "\n -c Set controlling terminal to stdin"
[3232]23
[1765]24#include "libbb.h"
[821]25
[2725]26int setsid_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
27int setsid_main(int argc UNUSED_PARAM, char **argv)
[821]28{
[3621]29 unsigned opt;
[821]30
[3621]31 opt_complementary = "-1"; /* at least one arg */
32 opt = getopt32(argv, "+c"); /* +: stop on first non-opt */
33 argv += optind;
34
[2725]35 /* setsid() is allowed only when we are not a process group leader.
36 * Otherwise our PID serves as PGID of some existing process group
[3621]37 * and cannot be used as PGID of a new process group.
38 *
39 * Example: setsid() below fails when run alone in interactive shell:
40 * $ setsid PROG
41 * because shell's child (setsid) is put in a new process group.
42 * But doesn't fail if shell is not interactive
43 * (and therefore doesn't create process groups for pipes),
44 * or if setsid is not the first process in the process group:
45 * $ true | setsid PROG
46 * or if setsid is executed in backquotes (`setsid PROG`)...
47 */
[2725]48 if (setsid() < 0) {
49 pid_t pid = fork_or_rexec(argv);
50 if (pid != 0) {
51 /* parent */
52 /* TODO:
53 * we can waitpid(pid, &status, 0) and then even
54 * emulate exitcode, making the behavior consistent
55 * in both forked and non forked cases.
56 * However, the code is larger and upstream
57 * does not do such trick.
58 */
[3621]59 return EXIT_SUCCESS;
[2725]60 }
[821]61
[2725]62 /* child */
63 /* now there should be no error: */
64 setsid();
65 }
[821]66
[3621]67 if (opt) {
68 /* -c: set (with stealing) controlling tty */
69 ioctl(0, TIOCSCTTY, 1);
70 }
71
[2725]72 BB_EXECVP_or_die(argv);
[821]73}
Note: See TracBrowser for help on using the repository browser.