]> andersk Git - test.git/commitdiff
Added --pidfile= option that can be used even if running in the foreground.
authorMarkus Gutschke <markus@shellinabox.com>
Sat, 11 Sep 2010 19:32:30 +0000 (19:32 +0000)
committerMarkus Gutschke <markus@shellinabox.com>
Sat, 11 Sep 2010 19:32:30 +0000 (19:32 +0000)
ChangeLog
config.h
configure
configure.ac
demo/vt100.js
shellinabox/shell_in_a_box.js
shellinabox/shellinaboxd.c
shellinabox/shellinaboxd.man.in
shellinabox/vt100.js

index 2e216b0d64b1026dfb712a52e3b6ea73d51bbaf8..c1c14bdd114352988b1a360a16b11ee5a0d079d4 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2010-09-11  Markus Gutschke  <markus@shellinabox.com>
+
+       * Added --pidfile= option that can be used even if running in the
+       foreground.
+
 2010-09-04  Markus Gutschke  <markus@shellinabox.com>
 
        * Added an optional on-screen keyboard. Must be activated by the
index 79359d1cd0dfdc1159b4818da865f8693e345d4b..14cbbcc81a01eaf5a2574320488ab40620587c05 100644 (file)
--- a/config.h
+++ b/config.h
 #define STDC_HEADERS 1
 
 /* Most recent revision number in the version control system */
-#define VCS_REVISION "222"
+#define VCS_REVISION "223"
 
 /* Version number of package */
 #define VERSION "2.10"
index 5b7e0e765a4a55f62e8c779fd40db520e1f12a42..118c49a9e68d74ec193ef54a2a99831dc62befb8 100755 (executable)
--- a/configure
+++ b/configure
@@ -2328,7 +2328,7 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
-VCS_REVISION=222
+VCS_REVISION=223
 
 
 cat >>confdefs.h <<_ACEOF
index 1aad87594c78c8bb34253a9c44ac38a465663245..ecd2bf944450aca433f5cf10443423ccb9d71c3c 100644 (file)
@@ -2,7 +2,7 @@ AC_PREREQ(2.57)
 
 dnl This is the one location where the authoritative version number is stored
 AC_INIT(shellinabox, 2.10, markus@shellinabox.com)
-VCS_REVISION=222
+VCS_REVISION=223
 AC_SUBST(VCS_REVISION)
 AC_DEFINE_UNQUOTED(VCS_REVISION, "${VCS_REVISION}",
                    [Most recent revision number in the version control system])
index e07066919977b005020622346e3fd8f0809cc21f..a36b76890db797a11249cce69ee209419176aa71 100644 (file)
@@ -2384,7 +2384,7 @@ VT100.prototype.toggleCursorBlinking = function() {
 };
 
 VT100.prototype.about = function() {
-  alert("VT100 Terminal Emulator " + "2.10 (revision 222)" +
+  alert("VT100 Terminal Emulator " + "2.10 (revision 223)" +
         "\nCopyright 2008-2010 by Markus Gutschke\n" +
         "For more information check http://shellinabox.com");
 };
index 7fdda062183f08f8d3cdd94def15ae6f0959b867..033127d20c00abf30f2c051c035307b70af8a365 100644 (file)
@@ -358,7 +358,7 @@ ShellInABox.prototype.extendContextMenu = function(entries, actions) {
 };
 
 ShellInABox.prototype.about = function() {
-  alert("Shell In A Box version " + "2.10 (revision 222)" +
+  alert("Shell In A Box version " + "2.10 (revision 223)" +
         "\nCopyright 2008-2010 by Markus Gutschke\n" +
         "For more information check http://shellinabox.com" +
         (typeof serverSupportsSSL != 'undefined' && serverSupportsSSL ?
index c432ffeb6b68bffa55fa86841c2ddc0e8c1bae9a..e80d2feeeada7dd6b15a13a588d25d5adf84b406 100644 (file)
@@ -52,6 +52,8 @@
 #include <limits.h>
 #include <locale.h>
 #include <poll.h>
+#include <setjmp.h>
+#include <signal.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -94,6 +96,9 @@ static char           *cgiSessionKey;
 static int            cgiSessions;
 static char           *cssStyleSheet;
 static struct UserCSS *userCSSList;
+static const char     *pidfile;
+static sigjmp_buf     jmpenv;
+static volatile int   exiting;
 
 static char *jsonEscape(const char *buf, int len) {
   static const char *hexDigit = "0123456789ABCDEF";
@@ -757,6 +762,7 @@ static void usage(void) {
           "      --localhost-only        only listen on 127.0.0.1\n"
           "      --no-beep               suppress all audio output\n"
           "  -n, --numeric               do not resolve hostnames\n"
+          "      --pidfile=PIDFILE       publish pid of daemon process\n"
           "  -p, --port=PORT             select a port (default: %d)\n"
           "  -s, --service=SERVICE       define one or more services\n"
           "%s"
@@ -822,6 +828,13 @@ static void destroyExternalFileHashEntry(void *arg, char *key, char *value) {
   free(value);
 }
 
+static void sigHandler(int signo, siginfo_t *info, void *context) {
+  if (exiting++) {
+    _exit(1);
+  }
+  siglongjmp(jmpenv, 1);
+}
+
 static void parseArgs(int argc, char * const argv[]) {
   int hasSSL               = serverSupportsSSL();
   if (!hasSSL) {
@@ -829,7 +842,6 @@ static void parseArgs(int argc, char * const argv[]) {
   }
   int demonize             = 0;
   int cgi                  = 0;
-  const char *pidfile      = NULL;
   int verbosity            = MSG_DEFAULT;
   externalFiles            = newHashMap(destroyExternalFileHashEntry, NULL);
   HashMap *serviceTable    = newHashMap(destroyServiceHashEntry, NULL);
@@ -855,6 +867,7 @@ static void parseArgs(int argc, char * const argv[]) {
       { "localhost-only",   0, 0,  0  },
       { "no-beep",          0, 0,  0  },
       { "numeric",          0, 0, 'n' },
+      { "pidfile",          1, 0,  0  },
       { "port",             1, 0, 'p' },
       { "service",          1, 0, 's' },
       { "disable-ssl",      0, 0, 't' },
@@ -894,7 +907,7 @@ static void parseArgs(int argc, char * const argv[]) {
         fatal("Only one pidfile can be given");
       }
       if (optarg && *optarg) {
-        pidfile            = strdup(optarg);
+        check(pidfile     = strdup(optarg));
       }
     } else if (!idx--) {
       // Certificate
@@ -957,6 +970,9 @@ static void parseArgs(int argc, char * const argv[]) {
       if (demonize) {
         fatal("CGI and background operations are mutually exclusive");
       }
+      if (pidfile) {
+        fatal("CGI operation and --pidfile= are mutually exclusive");
+      }
       if (port) {
         fatal("Cannot specify a port for CGI operation");
       }
@@ -987,7 +1003,7 @@ static void parseArgs(int argc, char * const argv[]) {
       check(path           = malloc(ptr - optarg + 1));
       memcpy(path, optarg, ptr - optarg);
       path[ptr - optarg]   = '\000';
-      file                 = strdup(ptr + 1);
+      check(file           = strdup(ptr + 1));
       if (getRefFromHashMap(externalFiles, path)) {
         fatal("Duplicate static-file definition for \"%s\".", path);
       }
@@ -1022,6 +1038,18 @@ static void parseArgs(int argc, char * const argv[]) {
     } else if (!idx--) {
       // Numeric
       numericHosts         = 1;
+    } else if (!idx--) {
+      // Pidfile
+      if (cgi) {
+        fatal("CGI operation and --pidfile= are mutually exclusive");
+      }
+      if (!optarg || !*optarg) {
+        fatal("Must specify a filename for --pidfile= option");
+      }
+      if (pidfile) {
+        fatal("Only one pidfile can be given");
+      }
+      check(pidfile        = strdup(optarg));
     } else if (!idx--) {
       // Port
       if (port) {
@@ -1138,21 +1166,23 @@ static void parseArgs(int argc, char * const argv[]) {
       _exit(0);
     }
     setsid();
-    if (pidfile) {
+  }
+  if (pidfile) {
 #ifndef O_LARGEFILE
 #define O_LARGEFILE 0
 #endif
-      int fd               = NOINTR(open(pidfile,
+    int fd                 = NOINTR(open(pidfile,
                                          O_WRONLY|O_TRUNC|O_LARGEFILE|O_CREAT,
                                          0644));
-      if (fd >= 0) {
-        char buf[40];
-        NOINTR(write(fd, buf, snprintf(buf, 40, "%d", (int)getpid())));
-        check(!NOINTR(close(fd)));
-      }
+    if (fd >= 0) {
+      char buf[40];
+      NOINTR(write(fd, buf, snprintf(buf, 40, "%d", (int)getpid())));
+      check(!NOINTR(close(fd)));
+    } else {
+      free((char *)pidfile);
+      pidfile              = NULL;
     }
   }
-  free((char *)pidfile);
 }
 
 static void removeLimits() {
@@ -1278,7 +1308,20 @@ int main(int argc, char * const argv[]) {
   iterateOverHashMap(externalFiles, registerExternalFiles, server);
 
   // Start the server
-  serverLoop(server);
+  if (!sigsetjmp(jmpenv, 1)) {
+    // Clean up upon orderly shut down. Do _not_ cleanup if we die
+    // unexpectedly, as we cannot guarantee if we are still in a valid
+    // static. This means, we should never catch SIGABRT.
+    static const int signals[] = { SIGHUP, SIGINT, SIGQUIT, SIGTERM };
+    struct sigaction sa;
+    memset(&sa, 0, sizeof(sa));
+    sa.sa_sigaction = sigHandler;
+    sa.sa_flags   = SA_SIGINFO | SA_RESETHAND;
+    for (int i = 0; i < sizeof(signals)/sizeof(*signals); ++i) {
+      sigaction(signals[i], &sa, NULL);
+    }
+    serverLoop(server);
+  }
 
   // Clean up
   deleteServer(server);
@@ -1290,6 +1333,27 @@ int main(int argc, char * const argv[]) {
   free(services);
   free(certificateDir);
   free(cgiSessionKey);
+  if (pidfile) {
+    // As a convenience, remove the pidfile, if it is still the version that
+    // we wrote. In general, pidfiles are not expected to be incredibly
+    // reliable, as there is no way to properly deal with multiple programs
+    // accessing the same pidfile. But we at least make a best effort to be
+    // good citizens.
+    char buf[40];
+    int fd        = open(pidfile, O_RDONLY);
+    if (fd >= 0) {
+      ssize_t sz;
+      NOINTR(sz   = read(fd, buf, sizeof(buf)-1));
+      NOINTR(close(fd));
+      if (sz > 0) {
+        buf[sz]   = '\000';
+        if (atoi(buf) == getpid()) {
+          unlink(pidfile);
+        }
+      }
+    }
+    free((char *)pidfile);
+  }
   info("Done");
   _exit(0);
 }
index 9dbe40a654377625c997c58b62ffbd7a2544a5b9..c617bbf46d3c160cf1436b6d38286a80835fbc3e 100644 (file)
@@ -1,6 +1,6 @@
 '\" t
 .\" shellinaboxd.man -- Make command line applications available as AJAX web applications
-.\" Copyright (C) 2008-2009 Markus Gutschke <markus@shellinabox.com>
+.\" Copyright (C) 2008-2010 Markus Gutschke <markus@shellinabox.com>
 .\"
 .\" This program is free software; you can redistribute it and/or modify
 .\" it under the terms of the GNU General Public License version 2 as
@@ -44,7 +44,7 @@
 .\" The most up-to-date version of this program is always available from
 .\" http://shellinabox.com
 .\"
-.TH SHELLINABOXD 1 "Dec 03, 2009"
+.TH SHELLINABOXD 1 "Sep 11, 2010"
 .SH NAME
 shellinaboxd \- publish command line shell through AJAX interface
 .SH SYNOPSIS
@@ -65,6 +65,7 @@ shellinaboxd \- publish command line shell through AJAX interface
 [\ \fB--localhost-only\fP\ ]
 [\ \fB--no-beep\fP\ ]
 [\ \fB-n\fP\ | \fB--numeric\fP\ ]
+[\ \fB--pidfile=\fP\fIpidfile\fP\ ]
 [\ \fB-p\fP\ | \fB--port=\fP\fIport\fP\ ]
 [\ \fB-s\fP\ | \fB--service=\fP\fIservice\fP\ ]
 #ifdef HAVE_OPENSSL
@@ -188,7 +189,8 @@ should be configured to pass through the firewall.
 The
 .B --cgi
 option is mutually exclusive with the
-.B --background
+.BR --background ,
+.B --pidfile
 and
 .B --port
 options.
@@ -312,6 +314,12 @@ By default, host names of peers get resolved
 before logging them. As DNS look-ups can be expensive, it is possible
 to request logging of numeric IP addresses, instead.
 .TP
+\fB--pidfile=\fP\fIpidfile\fP
+The
+.B shellinaboxd
+daemon can be configured to store its process identifier in
+.IR pidfile .
+.TP
 \fB-p\fP\ |\ \fB--port=\fP\fIport\fP
 Unless overridden by this option, the web server listens on port 4200
 for incoming HTTP and HTTPS requests.
@@ -798,7 +806,7 @@ and
 .B --user
 options should be used to change to a dedicated user.
 .SH AUTHOR
-Copyright (C) 2008-2009 by Markus Gutschke
+Copyright (C) 2008-2010 by Markus Gutschke
 .RI < "markus@shellinabox.com" >.
 .P
 This program is free software; you can redistribute it and/or modify
index e07066919977b005020622346e3fd8f0809cc21f..a36b76890db797a11249cce69ee209419176aa71 100644 (file)
@@ -2384,7 +2384,7 @@ VT100.prototype.toggleCursorBlinking = function() {
 };
 
 VT100.prototype.about = function() {
-  alert("VT100 Terminal Emulator " + "2.10 (revision 222)" +
+  alert("VT100 Terminal Emulator " + "2.10 (revision 223)" +
         "\nCopyright 2008-2010 by Markus Gutschke\n" +
         "For more information check http://shellinabox.com");
 };
This page took 0.067028 seconds and 5 git commands to generate.