Added --pidfile= option that can be used even if running in the foreground.
git-svn-id: https://shellinabox.googlecode.com/svn/trunk@223 0da03de8-d603-11dd-86c2-0f8696b7b6f9
This commit is contained in:
parent
61b40ad475
commit
bdf1ba75bd
9 changed files with 99 additions and 22 deletions
|
@ -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
|
||||
|
|
2
config.h
2
config.h
|
@ -153,7 +153,7 @@
|
|||
#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"
|
||||
|
|
2
configure
vendored
2
configure
vendored
|
@ -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
|
||||
|
|
|
@ -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])
|
||||
|
|
|
@ -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");
|
||||
};
|
||||
|
|
|
@ -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 ?
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue