]> git.ipfire.org Git - thirdparty/util-linux.git/blame - sys-utils/setsid.c
setsid: exit when control terminal cannot be set
[thirdparty/util-linux.git] / sys-utils / setsid.c
CommitLineData
6dbe3af9
KZ
1/*
2 * setsid.c -- execute a command in a new session
3 * Rick Sladkey <jrs@world.std.com>
4 * In the public domain.
7eda085c 5 *
b50945d4 6 * 1999-02-22 Arkadiusz Miƛkiewicz <misiek@pld.ORG.PL>
7eda085c
KZ
7 * - added Native Language Support
8 *
c07ebfa1
KZ
9 * 2001-01-18 John Fremlin <vii@penguinpowered.com>
10 * - fork in case we are process group leader
11 *
6dbe3af9
KZ
12 */
13
cbfa3253 14#include <getopt.h>
6dbe3af9 15#include <stdio.h>
6dbe3af9 16#include <stdlib.h>
cbfa3253 17#include <unistd.h>
97669624 18#include <sys/ioctl.h>
cbfa3253
SK
19
20#include "c.h"
7eda085c 21#include "nls.h"
efb8854f 22#include "closestream.h"
6dbe3af9 23
cbfa3253
SK
24static void __attribute__ ((__noreturn__)) usage(FILE * out)
25{
7c3c355f 26 fputs(USAGE_HEADER, out);
8a2f04dd 27 fprintf(out, _(
7c3c355f
KZ
28 " %s [options] <program> [arguments ...]\n"),
29 program_invocation_short_name);
30
31 fputs(USAGE_OPTIONS, out);
32 fputs(_(" -c, --ctty set the controlling terminal to the current one\n"),
33 out);
34
35 fputs(USAGE_HELP, out);
36 fputs(USAGE_VERSION, out);
37
cbfa3253
SK
38 fprintf(out, USAGE_MAN_TAIL("setsid(1)"));
39 exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
40}
41
42int main(int argc, char **argv)
43{
44 int ch;
8a2f04dd
HH
45 int ctty = 0;
46
cbfa3253 47 static const struct option longopts[] = {
8a2f04dd 48 {"ctty", no_argument, NULL, 'c'},
cbfa3253
SK
49 {"version", no_argument, NULL, 'V'},
50 {"help", no_argument, NULL, 'h'},
51 {NULL, 0, NULL, 0}
52 };
53
7eda085c
KZ
54 setlocale(LC_ALL, "");
55 bindtextdomain(PACKAGE, LOCALEDIR);
56 textdomain(PACKAGE);
efb8854f 57 atexit(close_stdout);
cbfa3253 58
8a2f04dd 59 while ((ch = getopt_long(argc, argv, "+Vhc", longopts, NULL)) != -1)
cbfa3253
SK
60 switch (ch) {
61 case 'V':
62 printf(UTIL_LINUX_VERSION);
63 return EXIT_SUCCESS;
8a2f04dd
HH
64 case 'c':
65 ctty=1;
66 break;
cbfa3253
SK
67 case 'h':
68 usage(stdout);
69 default:
70 usage(stderr);
71 }
72
73 if (argc < 2)
74 usage(stderr);
75
c07ebfa1 76 if (getpgrp() == getpid()) {
cbfa3253 77 switch (fork()) {
c07ebfa1 78 case -1:
cbfa3253
SK
79 err(EXIT_FAILURE, _("fork"));
80 case 0:
81 /* child */
c07ebfa1 82 break;
cbfa3253
SK
83 default:
84 /* parent */
85 return 0;
c07ebfa1
KZ
86 }
87 }
cbfa3253
SK
88 if (setsid() < 0)
89 /* cannot happen */
90 err(EXIT_FAILURE, _("setsid failed"));
91
8a2f04dd
HH
92 if (ctty) {
93 if (ioctl(STDIN_FILENO, TIOCSCTTY, 1))
af6d2663 94 err(EXIT_FAILURE, _("failed to set the controlling terminal"));
8a2f04dd 95 }
b4479ffa 96 execvp(argv[optind], argv + optind);
07ff972e 97 err(EXIT_FAILURE, _("failed to execute %s"), argv[optind]);
6dbe3af9 98}