summaryrefslogtreecommitdiff
path: root/sys-utils/setsid.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys-utils/setsid.c')
-rw-r--r--sys-utils/setsid.c98
1 files changed, 98 insertions, 0 deletions
diff --git a/sys-utils/setsid.c b/sys-utils/setsid.c
new file mode 100644
index 0000000..071ccc4
--- /dev/null
+++ b/sys-utils/setsid.c
@@ -0,0 +1,98 @@
+/*
+ * setsid.c -- execute a command in a new session
+ * Rick Sladkey <jrs@world.std.com>
+ * In the public domain.
+ *
+ * 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL>
+ * - added Native Language Support
+ *
+ * 2001-01-18 John Fremlin <vii@penguinpowered.com>
+ * - fork in case we are process group leader
+ *
+ */
+
+#include <getopt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+
+#include "c.h"
+#include "nls.h"
+#include "closestream.h"
+
+static void __attribute__ ((__noreturn__)) usage(FILE * out)
+{
+ fputs(USAGE_HEADER, out);
+ fprintf(out, _(
+ " %s [options] <program> [arguments ...]\n"),
+ program_invocation_short_name);
+
+ fputs(USAGE_OPTIONS, out);
+ fputs(_(" -c, --ctty set the controlling terminal to the current one\n"),
+ out);
+
+ fputs(USAGE_HELP, out);
+ fputs(USAGE_VERSION, out);
+
+ fprintf(out, USAGE_MAN_TAIL("setsid(1)"));
+ exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
+}
+
+int main(int argc, char **argv)
+{
+ int ch;
+ int ctty = 0;
+
+ static const struct option longopts[] = {
+ {"ctty", no_argument, NULL, 'c'},
+ {"version", no_argument, NULL, 'V'},
+ {"help", no_argument, NULL, 'h'},
+ {NULL, 0, NULL, 0}
+ };
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+ atexit(close_stdout);
+
+ while ((ch = getopt_long(argc, argv, "+Vhc", longopts, NULL)) != -1)
+ switch (ch) {
+ case 'V':
+ printf(UTIL_LINUX_VERSION);
+ return EXIT_SUCCESS;
+ case 'c':
+ ctty=1;
+ break;
+ case 'h':
+ usage(stdout);
+ default:
+ usage(stderr);
+ }
+
+ if (argc < 2)
+ usage(stderr);
+
+ if (getpgrp() == getpid()) {
+ switch (fork()) {
+ case -1:
+ err(EXIT_FAILURE, _("fork"));
+ case 0:
+ /* child */
+ break;
+ default:
+ /* parent */
+ return 0;
+ }
+ }
+ if (setsid() < 0)
+ /* cannot happen */
+ err(EXIT_FAILURE, _("setsid failed"));
+
+ if (ctty) {
+ if (ioctl(STDIN_FILENO, TIOCSCTTY, 1))
+ warn(_("failed to set the controlling terminal"));
+ }
+ execvp(argv[optind], argv + optind);
+ err(EXIT_FAILURE, _("execvp failed"));
+}