summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>2011-03-09 01:50:53 -0500
committerEric S. Raymond <esr@thyrsus.com>2011-03-09 01:50:53 -0500
commit2663033714a98a9c9ea1165c330371b949faec0d (patch)
tree0090a6f172564371681b899f2a8663b2b78cf752
parent9d6dc2f1f95d0179c6175955c3dae0c5299e9a78 (diff)
downloadgpsd-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.c29
-rw-r--r--gps.h2
-rw-r--r--gpxlogger.c18
-rw-r--r--lcdgps.c24
-rw-r--r--libgps.xml26
-rw-r--r--libgps_core.c11
-rw-r--r--libgpsmm.cpp4
-rw-r--r--libgpsmm.h2
8 files changed, 36 insertions, 80 deletions
diff --git a/cgps.c b/cgps.c
index 2f1e9ba7..656b14fb 100644
--- a/cgps.c
+++ b/cgps.c
@@ -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);
}
diff --git a/gps.h b/gps.h
index 1bb048bb..22517527 100644
--- a/gps.h
+++ b/gps.h
@@ -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);
}
diff --git a/lcdgps.c b/lcdgps.c
index 1719fc33..b92033b2 100644
--- a/lcdgps.c
+++ b/lcdgps.c
@@ -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);
}
diff --git a/libgps.xml b/libgps.xml
index a201306b..b71af88d 100644
--- a/libgps.xml
+++ b/libgps.xml
@@ -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(&amp;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 (&amp;gps_data)) {
+ if (gps_waiting (&amp;gps_data, 500)) {
errno = 0;
if (gps_read (&amp;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)
diff --git a/libgpsmm.h b/libgpsmm.h
index 3c77a403..93258df2 100644
--- a/libgpsmm.h
+++ b/libgpsmm.h
@@ -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: