]> Zhao Yanbai Git Server - minix.git/commitdiff
Add nohup tool (approved by Ben)
authorErik van der Kouwe <erik@minix3.org>
Tue, 6 Oct 2009 14:16:35 +0000 (14:16 +0000)
committerErik van der Kouwe <erik@minix3.org>
Tue, 6 Oct 2009 14:16:35 +0000 (14:16 +0000)
commands/simple/Makefile
commands/simple/nohup.c [new file with mode: 0644]
man/man1/nohup.1 [new file with mode: 0644]

index 41e631021b6282071ab5433cbd4f45a134c99a47..b40e199ea4998d068697616339e87a3d6962990b 100755 (executable)
@@ -133,6 +133,7 @@ ALL = \
        mt \
        nm \
        newroot \
+       nohup \
        nonamed \
        nice \
        od \
@@ -591,6 +592,10 @@ nice:      nice.c
        $(CCLD) -o $@ $<
        @install -S 8kw $@
 
+nohup: nohup.c
+       $(CCLD) -o $@ $<
+       @install -S 4kw $@
+
 nonamed:       nonamed.c
        $(CCLD) -o $@ $<
        @install -S 8kw $@
@@ -1022,6 +1027,7 @@ install:  \
        /usr/bin/newroot \
        /usr/bin/nm \
        /usr/bin/nice \
+       /usr/bin/nohup \
        /usr/bin/nonamed \
        /usr/bin/od \
        /usr/bin/passwd \
@@ -1443,6 +1449,9 @@ install:  \
 /usr/bin/nice: nice
        install -cs -o bin $< $@
 
+/usr/bin/nohup:        nohup
+       install -cs -o bin $< $@
+
 /usr/bin/nonamed:      nonamed
        install -cs -o bin $< $@
 
diff --git a/commands/simple/nohup.c b/commands/simple/nohup.c
new file mode 100644 (file)
index 0000000..94f9584
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2009, Erik van der Kouwe
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, 
+ *    this list of conditions and the following disclaimer. 
+ * 2. Redistributions in binary form must reproduce the above copyright notice, 
+ *    this list of conditions and the following disclaimer in the documentation 
+ *    and/or other materials provided with the distribution. 
+ * 3. The name of the author may not be used to endorse or promote products 
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * Functionality implemented according to this specification:
+ * http://www.opengroup.org/onlinepubs/000095399/utilities/nohup.html
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#define NOHUP_OUT_FILENAME "nohup.out"
+
+static void print_usage(const char *argv0)
+{
+       printf("Usage: %s command [arg...]\n", argv0);
+}
+
+static int redirect_tty(void)
+{
+       int fd;
+       char buffer[PATH_MAX + 1], *home;
+
+       /* redirect stdout to a file if needed */
+       if (isatty(STDOUT_FILENO))
+       {
+               /* first try: current directory */
+               fd = open(NOHUP_OUT_FILENAME, O_WRONLY | O_APPEND | O_CREAT, S_IRUSR | S_IWUSR);
+               if (fd < 0)
+               {
+                       /* alternative: home directory */
+                       home = getenv("HOME");
+                       if (home)
+                       {
+                               snprintf(buffer, sizeof(buffer), "%s/%s", home, NOHUP_OUT_FILENAME);
+                               buffer[sizeof(buffer) - 1] = 0;
+                               fd = open(buffer, O_WRONLY | O_APPEND | O_CREAT, S_IRUSR | S_IWUSR);
+                       }
+               }
+                               
+               if (fd < 0)
+               {
+                       perror("cannot create " NOHUP_OUT_FILENAME " and $HOME/" NOHUP_OUT_FILENAME);
+                       return -1;
+               }
+               
+               /* move the fd to stdout */
+               if (dup2(fd, STDOUT_FILENO) < 0 || close(fd) < 0)
+               {
+                       perror("cannot redirect stdout");
+                       return -1;
+               }
+       }
+       
+       /* redirect stderr to stdout if needed */
+       if (isatty(STDERR_FILENO))
+       {
+               if (dup2(STDOUT_FILENO, STDERR_FILENO) < 0)
+               {
+                       perror("cannot redirect stderr");
+                       return -1;
+               }
+       }
+
+       return 0;
+}
+
+int main(int argc, char **argv)
+{
+       struct sigaction sa;
+
+       /* check parameters */
+       if (argc < 2)
+       {
+               print_usage(argv[0]);
+               return 127;
+       }
+
+       /* ignore SIGHUP */
+       sa.sa_handler = SIG_IGN;
+       sigemptyset(&sa.sa_mask);
+       sa.sa_flags = 0;
+       if (sigaction(SIGHUP, &sa, NULL) < 0)
+       {
+               perror("cannot ignore SIGHUP");
+               return 127;
+       }
+
+       /* redirect TTY input and output */
+       if (redirect_tty() < 0)
+               return 127;
+
+       /* run the command */
+       execvp(argv[1], argv + 1);
+       perror("cannot execute");
+
+       /* exit code depends on whether the utility was found */
+       switch (errno)
+       {
+               case ELOOP:
+               case ENAMETOOLONG:
+               case ENOENT:
+               case ENOTDIR:
+                       /* utility not found */
+                       return 127;
+
+               default:
+                       /* exec failed for other reason */
+                       return 126;
+       }
+}
diff --git a/man/man1/nohup.1 b/man/man1/nohup.1
new file mode 100644 (file)
index 0000000..daa848e
--- /dev/null
@@ -0,0 +1,19 @@
+.TH NOHUP 1
+.SH NAME
+nohup \- ignore hangup signal
+.SH SYNOPSIS
+\fBnohup\fP \fIutility\fP [\fIargument\fP...]
+.SH DESCRIPTION
+The
+.B nohup
+utility runs \fIutility\fP while ignoring the SIGHUP signal. This 
+allows the process to continue running after the current terminal
+exits, for example when logging off a telnet session. 
+
+Unless output is explicitly redirected when invoking nohup, output is 
+appended to a file named nohup.out. This file is created in the current
+directory or, if this is not possible, in $HOME. If the standard error 
+stream is not explicitly redirected, it is sent to the standard output.
+.SH AUTHOR
+This manual page and the utility were written by Erik van der Kouwe 
+<vdkouwe@cs.vu.nl>.