diff options
author | Jeff Francis <jeff@gritch.org> | 2008-07-31 17:33:09 +0000 |
---|---|---|
committer | Jeff Francis <jeff@gritch.org> | 2008-07-31 17:33:09 +0000 |
commit | 4272432d845253c97966703d68c5b0746796f795 (patch) | |
tree | 6e2a2feabd8eb9cb98c78c317e0862faa6726c24 /gpspipe.c | |
parent | 8fe9919500bf73b8234d63eb6c9a5787fa67d0bd (diff) | |
download | gpsd-4272432d845253c97966703d68c5b0746796f795.tar.gz |
Add options to gpspipe to run as a daemon...
...to write output to a file (instead of stdout), and to sleep for ten
seconds before attempting to connect to gpsd (useful when running from
/etc/init.d/ as a daemon).
Diffstat (limited to 'gpspipe.c')
-rw-r--r-- | gpspipe.c | 97 |
1 files changed, 92 insertions, 5 deletions
@@ -45,6 +45,42 @@ static void spinner(unsigned int, unsigned int); static struct termios oldtio, newtio; static char serbuf[255]; +/* Daemonize me. */ +static void daemonize(void) { + int i; + + /* Run as my child. */ + i=fork(); + if (i<0) exit(1); /* fork error */ + if (i>0) exit(0); /* parent exits */ + + /* Obtain a new process group. */ + setsid(); + + /* Close all open descriptors. */ + for(i=getdtablesize();i>=0;--i) + close(i); + + /* Reopen STDIN, STDOUT, STDERR to /dev/null. */ + i=open("/dev/null",O_RDWR); /* STDIN */ + dup(i); /* STDOUT */ + dup(i); /* STDERR */ + + /* Know thy mask. */ + umask(027); + + /* Run from a known spot. */ + chdir("/"); + + /* Catch child sig */ + signal(SIGCHLD,SIG_IGN); + + /* Ignore tty signals */ + signal(SIGTSTP,SIG_IGN); + signal(SIGTTOU,SIG_IGN); + signal(SIGTTIN,SIG_IGN); +} + /* open the serial port and set it up */ static void open_serial(char* device) { @@ -83,17 +119,21 @@ static void usage(void) { (void)fprintf(stderr, "Usage: gpspipe [OPTIONS] [server[:port[:device]]]\n\n" "SVN ID: $Id$ \n" + "-d Run as a daemon.\n" + "-f [file] Write output to file.\n" "-h Show this help.\n" "-r Dump raw NMEA.\n" "-R Dump super-raw mode (GPS binary).\n" "-w Dump gpsd native data.\n" "-j Turn on server-side buffering.\n" + "-l Sleep for ten seconds before connecting to gpsd.\n" "-t Time stamp the data.\n" "-s [serial dev] emulate a 4800bps NMEA GPS on serial port (use with '-r').\n" "-n [count] exit after count packets.\n" "-v Print a little spinner.\n" "-V Print version and exit.\n\n" "You must specify one, or both, of -r/-w.\n" + "You must use -f if you use -d.\n" ); } @@ -103,17 +143,22 @@ int main( int argc, char **argv) char buf[4096]; ssize_t wrote = 0; bool timestamp = false; + bool daemon = false; + bool binary = false; + bool sleepy = false; bool new_line = true; long count = -1; int option; unsigned int vflag = 0, l = 0; + FILE * fd; char *arg = NULL, *colon1, *colon2, *device = NULL; char *port = DEFAULT_GPSD_PORT, *server = "127.0.0.1"; char *serialport = NULL; + char *filename = NULL; buf[0] = '\0'; - while ((option = getopt(argc, argv, "?hrRwjtvVn:s:")) != -1) { + while ((option = getopt(argc, argv, "?dlhrRwjtvVn:s:f:")) != -1) { switch (option) { case 'n': count = strtol(optarg, 0, 0); @@ -122,8 +167,15 @@ int main( int argc, char **argv) (void)strlcat(buf, "r=1;", sizeof(buf)); break; case 'R': + binary=true; (void)strlcat(buf, "r=2;", sizeof(buf)); break; + case 'd': + daemon = true; + break; + case 'l': + sleepy = true; + break; case 't': timestamp = true; break; @@ -142,6 +194,9 @@ int main( int argc, char **argv) case 's': serialport = optarg; break; + case 'f': + filename = optarg; + break; case '?': case 'h': default: @@ -155,6 +210,11 @@ int main( int argc, char **argv) exit(1); } + if (filename==NULL && daemon==true) { + (void)fprintf(stderr, "gpsipipe: use of '-d' requires '-f'.\n"); + exit(1); + } + if (strstr(buf, "r=")==NULL && strstr(buf, "w=1")==NULL) { (void)fprintf(stderr, "gpspipe: one of '-R', '-r' or '-w' is required.\n"); exit(1); @@ -187,6 +247,33 @@ int main( int argc, char **argv) } /*@ +branchstate @*/ + /* Sleep for ten seconds if the user requested it. */ + if (sleepy) + sleep(10); + + /* Daemonize if the user requested it. */ + if (daemon) + daemonize(); + + /* Open the output file if the user requested it. If the user + requested '-R', we use the 'b' flag in fopen() to "do the right + thing" in non-linux/unix OSes. */ + if (filename==NULL) { + fd = stdout; + } else { + if (binary) + fd = fopen(filename,"wb"); + else + fd = fopen(filename,"w"); + + if (fd < 0) { + (void)fprintf(stderr, + "gpspipe: unable to open output file: %s\n", + filename); + exit(1); + } + } + /* Open the serial port and set it up. */ if (serialport) open_serial(serialport); @@ -209,7 +296,7 @@ int main( int argc, char **argv) exit(1); } - if (isatty(STDERR_FILENO) == 0) + if ((isatty(STDERR_FILENO) == 0) || (daemon==true)) vflag = 0; for(;;) { @@ -230,14 +317,14 @@ int main( int argc, char **argv) time_t now = time(NULL); new_line = 0; - if (fprintf(stdout, "%.24s :", ctime(&now)) <= 0) { + if (fprintf(fd, "%.24s :", ctime(&now)) <= 0) { (void)fprintf(stderr, "gpspipe: write error, %s(%d)\n", strerror(errno), errno); exit(1); } } - if (fputc(c, stdout) == EOF) { + if (fputc(c, fd) == EOF) { fprintf( stderr, "gpspipe: Write Error, %s(%d)\n", strerror(errno), errno); exit(1); @@ -256,7 +343,7 @@ int main( int argc, char **argv) new_line = true; /* flush after every good line */ - if (fflush(stdout)) { + if (fflush(fd)) { (void)fprintf(stderr, "gpspipe: fflush Error, %s(%d)\n", strerror(errno), errno); exit(1); |