From 603fb9b1df0e95cbd5af23615f96f2aa16ba7407 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 31 May 2004 22:21:42 +0000 Subject: Add support for writing a pidfile and cleaning up the connection on exit --- pand/main.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- pand/pand.1 | 6 ++++ 2 files changed, 105 insertions(+), 5 deletions(-) diff --git a/pand/main.c b/pand/main.c index 1bc1d9e0..d4a29867 100644 --- a/pand/main.c +++ b/pand/main.c @@ -43,6 +43,8 @@ #include #include +#include +#include #include #include @@ -61,6 +63,7 @@ static int use_sdp = 1; static int use_cache; static int encrypt; static int master; +static int cleanup; static int search_duration = 10; static struct { @@ -70,12 +73,14 @@ static struct { } cache; static char netdev[16] = "bnep%d"; - +static char *pidfile = NULL; static bdaddr_t src_addr = *BDADDR_ANY; static int src_dev = -1; volatile int terminate; +static void do_kill(char *dst); + enum { NONE, SHOW, @@ -276,9 +281,15 @@ static int create_connection(char *dst, bdaddr_t *bdaddr) run_devup(netdev, dst); - if (persist) + if (persist) { w4_hup(sk); + if (terminate && cleanup) { + syslog(LOG_INFO, "Disconnecting from %s.", dst); + do_kill(dst); + } + } + r = 0; } else { syslog(LOG_ERR, "Connect to %s failed. %s(%d)", @@ -386,6 +397,71 @@ void sig_term(int sig) terminate = 1; } +int write_pidfile(void) +{ + int fd; + FILE *f; + pid_t pid; + + do { + fd = open(pidfile, O_WRONLY|O_TRUNC|O_CREAT|O_EXCL, 0644); + if (fd == -1) { + /* Try to open the file for read. */ + fd = open(pidfile, O_RDONLY); + if(fd == -1) { + syslog(LOG_ERR, "Could not read old pidfile: %s(%d)", strerror(errno), errno); + return -1; + } + + /* We're already running; send a SIGHUP (we presume that they + * are calling ifup for a reason, so they probably want to + * rescan) and then exit cleanly and let things go on in the + * background. Muck with the filename so that we don't go + * deleting the pid file for the already-running instance. + */ + f = fdopen(fd, "r"); + if (!f) { + syslog(LOG_ERR, "Could not fdopen old pidfile: %s(%d)", strerror(errno), errno); + close(fd); + return -1; + } + + pid = 0; + fscanf(f, "%d", &pid); + fclose(f); + + if (pid) { + /* Try to kill it. */ + if (kill(pid, SIGHUP) == -1) { + /* No such pid; remove the bogus pid file. */ + syslog(LOG_INFO, "Removing stale pidfile"); + unlink(pidfile); + fd = -1; + } else { + /* Got it. Don't mess with the pid file on + * our way out. */ + syslog(LOG_INFO, "Signalling existing process %d and exiting\n", pid); + pidfile = NULL; + return -1; + } + } + } + } while(fd == -1); + + f = fdopen(fd, "w"); + if (!f) { + syslog(LOG_ERR, "Could not fdopen new pidfile: %s(%d)", strerror(errno), errno); + close(fd); + unlink(pidfile); + return -1; + } + fprintf(f, "%d\n", getpid()); + fclose(f); + return 0; +} + + + static struct option main_lopts[] = { { "help", 0, 0, 'h' }, { "listen", 0, 0, 's' }, @@ -405,10 +481,12 @@ static struct option main_lopts[] = { { "encrypt", 0, 0, 'E' }, { "master", 0, 0, 'M' }, { "cache", 0, 0, 'C' }, + { "pidfile", 1, 0, 'P' }, + { "autozap", 0, 0, 'z' }, { 0, 0, 0, 0 } }; -static char main_sopts[] = "hsc:k:Kr:i:S:lnp::DQ::EMC::"; +static char main_sopts[] = "hsc:k:Kr:i:S:lnp::DQ::EMC::P:z"; static char main_help[] = "PAN daemon version " VERSION " \n" @@ -418,6 +496,7 @@ static char main_help[] = "\t--show --list -l Show active PAN connections\n" "\t--listen -s Listen for PAN connections\n" "\t--connect -c Create PAN connection\n" + "\t--autozap -z Disconnect automatically on exit\n" "\t--search -Q[duration] Search and connect\n" "\t--kill -k Kill PAN connection\n" "\t--killall -K Kill all PAN connections\n" @@ -430,7 +509,8 @@ static char main_help[] = "\t--master -M Become the master of a piconet\n" "\t--nodetach -n Do not become a daemon\n" "\t--persist -p[interval] Persist mode\n" - "\t--cache -C[valid] Cache addresses\n"; + "\t--cache -C[valid] Cache addresses\n" + "\t--pidfile -P Create PID file\n"; int main(int argc, char **argv) { @@ -519,7 +599,15 @@ int main(int argc, char **argv) else use_cache = 2; break; - + + case 'P': + pidfile = strdup(optarg); + break; + + case 'z': + cleanup = 1; + break; + case 'h': default: printf(main_help); @@ -588,6 +676,9 @@ int main(int argc, char **argv) } } + if (pidfile && write_pidfile()) + return -1; + if (dst) { /* Disable cache invalidation */ use_cache = 0; @@ -607,5 +698,8 @@ int main(int argc, char **argv) break; } + if (pidfile) + unlink(pidfile); + return 0; } diff --git a/pand/pand.1 b/pand/pand.1 index a11a33c0..fbcc1ddd 100644 --- a/pand/pand.1 +++ b/pand/pand.1 @@ -56,4 +56,10 @@ Persist mode .TP \fB\-\-cache\fR \fB\-C[valid]\fR Cache addresses +.TP +\fB\-\-autozap\fR \fB\-z\fR +Disconnect automatically on exit +.TP +\fB\-\-pidfile\fR \fB\-P \fR +Create PID file -- cgit