summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2013-08-29 17:12:25 +0200
committerHarald Welte <laforge@gnumonks.org>2013-08-29 17:12:25 +0200
commitcb65bc53489a3881783e8213e3c4b2a5cc507337 (patch)
treec6da940b35e36f7edc31c59a58f73c49bbf87465
parent0db898e4b8870ecc8e703ca3b6cafb6281077188 (diff)
downloadgpsdate-cb65bc53489a3881783e8213e3c4b2a5cc507337.tar.gz
gpsdate-cb65bc53489a3881783e8213e3c4b2a5cc507337.tar.bz2
gpsdate-cb65bc53489a3881783e8213e3c4b2a5cc507337.tar.xz
gpsdate-cb65bc53489a3881783e8213e3c4b2a5cc507337.zip
avoid using 99% CPU in case gpsd dies
This addresses and issue when gpsdate is running and the gpsd will be killed (testing coredump handling). The issue is within the libgps cod itself that doesn't handle the result(0) of the recv syscall correctly and keeps on looping. Now in a normal system gpsdate should only execute at the beginning and exit once there is a date. So the window for this runtime failure is quite low. Bug reported by Holger Freyther.
-rw-r--r--gpsdate.c22
1 files changed, 21 insertions, 1 deletions
diff --git a/gpsdate.c b/gpsdate.c
index 3d8447a..6b4f303 100644
--- a/gpsdate.c
+++ b/gpsdate.c
@@ -123,6 +123,26 @@ static int osmo_daemonize(void)
return 0;
}
+/* local copy, as the libgps official version ignores gps_read() result */
+static int my_gps_mainloop(struct gps_data_t *gdata,
+ int timeout,
+ void (*hook)(struct gps_data_t *gdata))
+{
+ int rc;
+
+ for (;;) {
+ if (!gps_waiting(gdata, timeout)) {
+ return -1;
+ } else {
+ rc = gps_read(gdata);
+ if (rc < 0)
+ return rc;
+ (*hook)(gdata);
+ }
+ }
+ return 0;
+}
+
int main(int argc, char **argv)
{
char *host = "localhost";
@@ -155,7 +175,7 @@ int main(int argc, char **argv)
/* We run in an endless loop. The only reasonable way to exit is after
* a correct GPS timestamp has been received in callback() */
while (1)
- gps_mainloop(&gpsdata, INT_MAX, callback);
+ my_gps_mainloop(&gpsdata, INT_MAX, callback);
gps_close(&gpsdata);