summaryrefslogtreecommitdiff
path: root/gpspipe.c
diff options
context:
space:
mode:
authorJeff Francis <jeff@gritch.org>2008-07-31 17:33:09 +0000
committerJeff Francis <jeff@gritch.org>2008-07-31 17:33:09 +0000
commit4272432d845253c97966703d68c5b0746796f795 (patch)
tree6e2a2feabd8eb9cb98c78c317e0862faa6726c24 /gpspipe.c
parent8fe9919500bf73b8234d63eb6c9a5787fa67d0bd (diff)
downloadgpsd-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.c97
1 files changed, 92 insertions, 5 deletions
diff --git a/gpspipe.c b/gpspipe.c
index aeb3946b..ea786004 100644
--- a/gpspipe.c
+++ b/gpspipe.c
@@ -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);