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