diff options
author | Eric S. Raymond <esr@thyrsus.com> | 2011-03-09 01:50:53 -0500 |
---|---|---|
committer | Eric S. Raymond <esr@thyrsus.com> | 2011-03-09 01:50:53 -0500 |
commit | 2663033714a98a9c9ea1165c330371b949faec0d (patch) | |
tree | 0090a6f172564371681b899f2a8663b2b78cf752 | |
parent | 9d6dc2f1f95d0179c6175955c3dae0c5299e9a78 (diff) | |
download | gpsd-2663033714a98a9c9ea1165c330371b949faec0d.tar.gz |
Give gps_waiting() a timeout argument. Use it systematically in test clients.
cgps and gpxlogger are live-tested and work. All regression tests pass.
-rw-r--r-- | cgps.c | 29 | ||||
-rw-r--r-- | gps.h | 2 | ||||
-rw-r--r-- | gpxlogger.c | 18 | ||||
-rw-r--r-- | lcdgps.c | 24 | ||||
-rw-r--r-- | libgps.xml | 26 | ||||
-rw-r--r-- | libgps_core.c | 11 | ||||
-rw-r--r-- | libgpsmm.cpp | 4 | ||||
-rw-r--r-- | libgpsmm.h | 2 |
8 files changed, 36 insertions, 80 deletions
@@ -84,7 +84,6 @@ /* This is the maximum size we need for the 'satellites' window. */ #define MAX_SATWIN_SIZE (MAX_POSSIBLE_SATS + SATWIN_OVERHEAD) -#include <sys/time.h> /* for select() */ #include <stdio.h> #include <stdlib.h> #include <stdbool.h> @@ -732,10 +731,6 @@ int main(int argc, char *argv[]) { int option; int c; - - struct timeval timeout; - fd_set rfds; - int data; unsigned int flags = WATCH_ENABLE; /*@ -observertrans @*/ @@ -861,25 +856,10 @@ int main(int argc, char *argv[]) /* heart of the client */ for (;;) { - - /* watch to see when it has input */ - FD_ZERO(&rfds); - FD_SET(gpsdata.gps_fd, &rfds); - - /* wait up to five seconds. */ - timeout.tv_sec = 5; - timeout.tv_usec = 0; - - /* check if we have new information */ - data = select(gpsdata.gps_fd + 1, &rfds, NULL, NULL, &timeout); - - if (data == -1) { - if (errno == EINTR) { - continue; - } - fprintf(stderr, "cgps: socket error 3\n"); + if (!gps_waiting(&gpsdata, 5000000)) { + fprintf(stderr, "cgps: error while waiting\n"); exit(2); - } else if (data) { + } else { errno = 0; if (gps_read(&gpsdata) == -1) { fprintf(stderr, "cgps: socket error 4\n"); @@ -918,7 +898,4 @@ int main(int argc, char *argv[]) break; } } - - /* this chould not actually be reachable */ - exit(0); } @@ -1424,7 +1424,7 @@ extern int gps_open(/*@null@*/const char *, /*@null@*/const char *, extern int gps_close(struct gps_data_t *); extern int gps_send(struct gps_data_t *, const char *, ... ); extern int gps_read(/*@out@*/struct gps_data_t *); -extern bool gps_waiting(struct gps_data_t *); +extern bool gps_waiting(struct gps_data_t *, int); extern int gps_stream(struct gps_data_t *, unsigned int, /*@null@*/void *); extern const char /*@observer@*/ *gps_errstr(const int); diff --git a/gpxlogger.c b/gpxlogger.c index ffe8899d..99e465ca 100644 --- a/gpxlogger.c +++ b/gpxlogger.c @@ -12,7 +12,6 @@ #include <errno.h> #include <libgen.h> #include <signal.h> -#include <sys/time.h> /* for select() */ #ifndef S_SPLINT_S #include <unistd.h> #endif /* S_SPLINT_S */ @@ -299,7 +298,6 @@ static struct fixsource_t source; /*@-mustfreefresh -compdestroy@*/ static int socket_mainloop(void) { - fd_set fds; unsigned int flags = WATCH_ENABLE; if (gps_open(source.server, source.port, &gpsdata) != 0) { @@ -314,20 +312,10 @@ static int socket_mainloop(void) (void)gps_stream(&gpsdata, flags, source.device); for (;;) { - int data; - struct timeval tv; - - FD_ZERO(&fds); - FD_SET(gpsdata.gps_fd, &fds); - - tv.tv_usec = 250000; - tv.tv_sec = 0; - data = select(gpsdata.gps_fd + 1, &fds, NULL, NULL, &tv); - - if (data == -1) { - (void)fprintf(stderr, "%s\n", strerror(errno)); + if (!gps_waiting(&gpsdata, 5000000)) { + (void)fprintf(stderr, "%s: error whille waiting\n", progname); break; - } else if (data) { + } else { (void)gps_read(&gpsdata); conditionally_log_fix(&gpsdata); } @@ -45,7 +45,6 @@ #ifndef INADDR_ANY #include <netinet/in.h> #endif /* INADDR_ANY */ -#include <sys/time.h> /* for select() */ #include <stdlib.h> #include <string.h> #include <math.h> @@ -290,10 +289,6 @@ int main(int argc, char *argv[]) struct sockaddr_in localAddr, servAddr; struct hostent *h; - struct timeval timeout; - fd_set rfds; - int data; - int n; for(n=0;n<CLIMB;n++) climb[n]=0.0; @@ -446,23 +441,10 @@ int main(int argc, char *argv[]) (void)gps_stream(&gpsdata, flags, source.device); for (;;) { /* heart of the client */ - - /* watch to see when it has input */ - FD_ZERO(&rfds); - FD_SET(gpsdata.gps_fd, &rfds); - - /* wait up to five seconds. */ - timeout.tv_sec = 5; - timeout.tv_usec = 0; - - /* check if we have new information */ - data = select(gpsdata.gps_fd + 1, &rfds, NULL, NULL, &timeout); - - if (data == -1) { - fprintf( stderr, "lcdgps: socket error\n"); + if (!gps_waiting(&gpsdata, 50000000)) { + fprintf( stderr, "lcdgps: error while waiting\n"); exit(2); - } - else if (data) { + } else { (void)gps_read(&gpsdata); update_lcd(&gpsdata); } @@ -44,6 +44,7 @@ C: <funcprototype> <funcdef>bool <function>gps_waiting</function></funcdef> <paramdef>struct gps_data_t *<parameter>gpsdata</parameter></paramdef> + <paramdef>int <parameter>timeout</parameter></paramdef> </funcprototype> <funcprototype> <funcdef>void <function>gps_close</function></funcdef> @@ -119,16 +120,21 @@ alternative.</para> <para><function>gps_read()</function> accepts a response, or sequence of responses, from the daemon and interprets it as though it were a query response (the return value is as for a query). This function -does a nonblocking read waiting for data from the daemon; it returns a +does a nonblocking read for data from the daemon; it returns a count of bytes read for success, -1 with errno set on a Unix-level read error, -1 with errno not set if the socket to the daemon has closed, and 0 if POLL_NONBLOCK was passed to gps_stream() and no data is yet available.</para> -<para><function>gps_waiting()</function> can be used to check -whether there is data from the daemon. It returns true if there is, -false on no data waiting or error condition. It does not block -waiting for input.</para> +<para><function>gps_waiting()</function> can be used to check whether +there is data from the daemon. The argument is the maximum amount of +time to wait on input before returning. It returns true if there +inmput waiting, false on timeout (no data waiting) or error +condition. This function is a convenience wrapper around a +<citerefentry><refentrytitle>select</refentrytitle><manvolnum>2</manvolnum></citerefentry> +call, and zeros <varname>errno</varname> on entry; you can test +<varname>errno</varname> after exit to get more information about +error conditions.</para> <para><function>gps_stream()</function> asks <application>gpsd</application> to stream the reports it has at you, @@ -136,10 +142,10 @@ to be made available when you poll. It is preferable to the older-style (pre-2.90) way of doing this, <function>gps_query()</function> with a "w+" argument, because it insulates your code from whether your client library and your -<application>gpsd</application> are using old or new protocol. -The second argument is a flag mask that sets various policy bits; -see the list below. Calling <function>gps_stream()</function> -more than once with different flag masks is allowed.</para> +<application>gpsd</application> are using old or new protocol. The +second argument is a flag mask that sets various policy bits; see the +list below. Calling <function>gps_stream()</function> more than once +with different flag masks is allowed.</para> <variablelist> <varlistentry> @@ -247,7 +253,7 @@ libgps interface code from (void) gps_stream(&gps_data, WATCH_ENABLE | WATCH_JSON, NULL); /* Put this in a loop with a call to a high resolution sleep () in it. */ - if (gps_waiting (&gps_data)) { + if (gps_waiting (&gps_data, 500)) { errno = 0; if (gps_read (&gps_data) == -1) { ... diff --git a/libgps_core.c b/libgps_core.c index 886b7eca..533aaec3 100644 --- a/libgps_core.c +++ b/libgps_core.c @@ -499,21 +499,24 @@ int gps_unpack(char *buf, struct gps_data_t *gpsdata) /*@ +compdef @*/ /*@ -branchstate +usereleased +mustfreefresh +nullstate +usedef @*/ -bool gps_waiting(struct gps_data_t * gpsdata) +bool gps_waiting(struct gps_data_t * gpsdata, int timeout) /* is there input waiting from the GPS? */ { #ifndef USE_QT fd_set rfds; struct timeval tv; - libgps_debug_trace((DEBUG_CALLS, "gps_waiting(): %d\n", waitcount++)); + libgps_debug_trace((DEBUG_CALLS, "gps_waiting(%d): %d\n", timeout, waitcount++)); if (gpsdata->waiting > 0) return true; + /* we might want to check for EINTR if this returns false */ + errno = 0; + FD_ZERO(&rfds); FD_SET(gpsdata->gps_fd, &rfds); - tv.tv_sec = 0; - tv.tv_usec = 1; + tv.tv_sec = timeout / 1000000; + tv.tv_usec = timeout % 1000000; /* all error conditions return "not waiting" -- crude but effective */ return (select(gpsdata->gps_fd + 1, &rfds, NULL, NULL, &tv) == 1); #else diff --git a/libgpsmm.cpp b/libgpsmm.cpp index f7d2354b..1c672c65 100644 --- a/libgpsmm.cpp +++ b/libgpsmm.cpp @@ -56,9 +56,9 @@ struct gps_data_t* gpsmm::read(void) } } -bool gpsmm::waiting(void) +bool gpsmm::waiting(int timeout) { - return gps_waiting(gps_data()); + return gps_waiting(gps_data(), timeout); } void gpsmm::clear_fix(void) @@ -32,7 +32,7 @@ class LIBQGPSMMSHARED_EXPORT gpsmm { struct gps_data_t* stream(int); //set watcher and policy flags struct gps_data_t* read(void); //block until gpsd returns new data, then return the updated struct int close(void); // close the GPS - bool waiting(void); //nonblocking check for data waitin + bool waiting(int); // blocking check for data waiting void clear_fix(void); void enable_debug(int, FILE*); private: |