summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>2015-01-31 15:16:55 -0500
committerEric S. Raymond <esr@thyrsus.com>2015-01-31 15:16:55 -0500
commit6ee9556f2fea231303a488f07a8b0e0a9f552dc4 (patch)
tree0427b34e9b53f0317b3c575ef5cd507bae92be35
parent2bab8b2a7f810a4a430def430cbae80d74c572c6 (diff)
downloadgpsd-6ee9556f2fea231303a488f07a8b0e0a9f552dc4.tar.gz
Back out the attempt to use VTIME.
According to Matthias Drochner at http://lists.lysator.liu.se/pipermail/lsh-bugs/2003q4/000151.html: I thought I'd give lsh a try, just to see how it compares to openssh... The client didn't work well on NetBSD, got a message like "unexpected EWOULDBLOCK" on each keystroke. Looked a bit deeper and found that stdin is set to O_NONBLOCK and a raw tty mode with c_cc[VMIN] > 1 and c_cc[VTIME] > 0. I'll append a little test program which does the same. I've tried it on 3 operating systems (Linux, NetBSD, Digital UNIX), and it behaves differently on each: -on Linux, if a key is pressed, the read returns immediately with that one character -on NetBSD, the read returns with no data but EWOULDBLOCK -on D'UNIX, the poll() doesn't teturn before 4 keypresses are done; the read() returns these 4 characters Indeed, in SUSv2's termios page is a sentence which says that if both O_NONBLOCK and VTIME>0 are set, the behaviour is more or less undefined. I've solved my immediate problems by setting VMIN to 1 instead of 4 in unix_interact.c:do_make_raw(), but VTIME is still pointless, so I wouldn't call this a clean solution. All regression tests pass.
-rw-r--r--driver_evermore.c1
-rw-r--r--driver_garmin.c3
-rw-r--r--driver_geostar.c1
-rw-r--r--driver_italk.c1
-rw-r--r--driver_navcom.c1
-rw-r--r--driver_nmea2000.c1
-rw-r--r--driver_oncore.c1
-rw-r--r--driver_proto.c2
-rw-r--r--driver_sirf.c1
-rw-r--r--driver_superstar2.c1
-rw-r--r--driver_tsip.c1
-rw-r--r--driver_ubx.c1
-rw-r--r--driver_zodiac.c1
-rw-r--r--drivers.c19
-rw-r--r--gpsd.h-tail2
-rw-r--r--gpsdecode.c2
-rw-r--r--libgpsd_core.c3
-rw-r--r--serial.c69
18 files changed, 14 insertions, 97 deletions
diff --git a/driver_evermore.c b/driver_evermore.c
index 92a99044..132d1db4 100644
--- a/driver_evermore.c
+++ b/driver_evermore.c
@@ -637,7 +637,6 @@ const struct gps_type_t driver_evermore =
#ifdef TIMEHINT_ENABLE
.time_offset = NULL, /* no method for NTP fudge factor */
#endif /* TIMEHINT_ENABLE */
- .minlength = 10, /* min packet length for chunked I/O */
};
/* *INDENT-ON* */
#endif /* defined(EVERMORE_ENABLE) && defined(BINARY_ENABLE) */
diff --git a/driver_garmin.c b/driver_garmin.c
index 7450d5f7..d9d4888d 100644
--- a/driver_garmin.c
+++ b/driver_garmin.c
@@ -1401,7 +1401,6 @@ const struct gps_type_t driver_garmin_usb_binary_old =
#ifdef TIMEHINT_ENABLE
.time_offset = garmin_time_offset,
#endif /* TIMEHINT_ENABLE */
- .minlength = 0; /* min packet length unknown */
};
/* *INDENT-ON* */
#endif /* __UNUSED__ */
@@ -1432,7 +1431,6 @@ const struct gps_type_t driver_garmin_usb_binary =
#ifdef TIMEHINT_ENABLE
.time_offset = garmin_time_offset,
#endif /* TIMEHINT_ENABLE */
- .minlength = 0, /* min packet length unknown */
};
/* *INDENT-ON* */
@@ -1462,7 +1460,6 @@ const struct gps_type_t driver_garmin_ser_binary =
#ifdef TIMEHINT_ENABLE
.time_offset = garmin_time_offset,
#endif /* TIMEHINT_ENABLE */
- .minlength = 0, /* min packet length unknown */
};
/* *INDENT-ON* */
diff --git a/driver_geostar.c b/driver_geostar.c
index 06b2d563..11e9ad78 100644
--- a/driver_geostar.c
+++ b/driver_geostar.c
@@ -640,7 +640,6 @@ const struct gps_type_t driver_geostar =
#ifdef TIMEHINT_ENABLE
.time_offset = geostar_time_offset,
#endif /* TIMEHINT_ENABLE */
- .minlength = 24, /* min packet length for the GeoStar */
};
/* *INDENT-ON* */
diff --git a/driver_italk.c b/driver_italk.c
index e1cdf483..051376c2 100644
--- a/driver_italk.c
+++ b/driver_italk.c
@@ -432,7 +432,6 @@ const struct gps_type_t driver_italk =
#ifdef TIMEHINT_ENABLE
.time_offset = NULL, /* no method for NTP fudge factor */
#endif /* TIMEHINT_ENABLE */
- .minlength = 30, /* min packet length for chunked output */
};
/* *INDENT-ON* */
#endif /* defined(ITRAX_ENABLE) && defined(BINARY_ENABLE) */
diff --git a/driver_navcom.c b/driver_navcom.c
index 067aef0b..925b7b61 100644
--- a/driver_navcom.c
+++ b/driver_navcom.c
@@ -1310,7 +1310,6 @@ const struct gps_type_t driver_navcom =
#ifdef TIMEHINT_ENABLE
.time_offset = NULL, /* no method for NTP fudge factor */
#endif /* TIMEHINT_ENABLE */
- .minlength = 10, /* min packet length for chunked I/O */
};
/* *INDENT-ON* */
diff --git a/driver_nmea2000.c b/driver_nmea2000.c
index 4059dbee..d74233b4 100644
--- a/driver_nmea2000.c
+++ b/driver_nmea2000.c
@@ -1700,7 +1700,6 @@ const struct gps_type_t driver_nmea2000 = {
#ifdef TIMEHINT_ENABLE
.time_offset = NULL,
#endif /* TIMEHINT_ENABLE */
- .minlength = 0, /* min packet length unknown */
};
/* *INDENT-ON* */
diff --git a/driver_oncore.c b/driver_oncore.c
index 569e1f4d..8cea6e7c 100644
--- a/driver_oncore.c
+++ b/driver_oncore.c
@@ -520,7 +520,6 @@ const struct gps_type_t driver_oncore = {
#ifdef TIMEHINT_ENABLE
.time_offset = oncore_time_offset, /* NTP offset array */
#endif /* TIMEHINT_ENABLE */
- .minlength = 38, /* min packet length for chunked I/O */
};
/* *INDENT-ON* */
#endif /* defined(ONCORE_ENABLE) && defined(BINARY_ENABLE) */
diff --git a/driver_proto.c b/driver_proto.c
index e8953cf8..bbbd7c0d 100644
--- a/driver_proto.c
+++ b/driver_proto.c
@@ -533,8 +533,6 @@ const struct gps_type_t driver__proto__binary = {
#ifdef TIMEHINT_ENABLE
.time_offset = _proto_time_offset,
#endif /* TIMEHINT_ENABLE */
- /* minimum length of packet, used for I/O optimization */
- .minlength = 0;
/* *INDENT-ON* */
};
#endif /* defined(_PROTO__ENABLE) && defined(BINARY_ENABLE) */
diff --git a/driver_sirf.c b/driver_sirf.c
index 87146ce7..20e7b513 100644
--- a/driver_sirf.c
+++ b/driver_sirf.c
@@ -1590,7 +1590,6 @@ const struct gps_type_t driver_sirf =
#ifdef TIMEHINT_ENABLE
.time_offset = sirf_time_offset,
#endif /* NTP_SHM_ENABLE */
- .minlength = 13, /* minimum SiRF packet length */
};
/* *INDENT-ON* */
#endif /* defined(SIRF_ENABLE) && defined(BINARY_ENABLE) */
diff --git a/driver_superstar2.c b/driver_superstar2.c
index 95d69cd4..94cc3320 100644
--- a/driver_superstar2.c
+++ b/driver_superstar2.c
@@ -585,7 +585,6 @@ const struct gps_type_t driver_superstar2 = {
#ifdef TIMEHINT_ENABLE
.time_offset = NULL, /* no method for NTP fudge factor */
#endif /* TIMEHINT_ENABLE */
- .minlength = 65, /* min packet length for chunked I/O */
};
/* *INDENT-ON* */
#endif /* defined(SUPERSTAR2_ENABLE) && defined(BINARY_ENABLE) */
diff --git a/driver_tsip.c b/driver_tsip.c
index 994da718..6134e3d9 100644
--- a/driver_tsip.c
+++ b/driver_tsip.c
@@ -1281,7 +1281,6 @@ const struct gps_type_t driver_tsip =
#ifdef TIMEHINT_ENABLE
.time_offset = tsip_time_offset,
#endif /* TIMEHINT_ENABLE */
- .minlength = 5, /* min packet length for chunked I/O */
};
/* *INDENT-ON* */
diff --git a/driver_ubx.c b/driver_ubx.c
index 260c8523..2f2a7358 100644
--- a/driver_ubx.c
+++ b/driver_ubx.c
@@ -992,7 +992,6 @@ const struct gps_type_t driver_ubx = {
#ifdef TIMEHINT_ENABLE
.time_offset = NULL, /* no method for NTP fudge factor */
#endif /* TIMEHINT_ENABLE */
- .minlength = 17, /* min packet length for chunked I/O */
};
/* *INDENT-ON* */
#endif /* defined(UBLOX_ENABLE) && defined(BINARY_ENABLE) */
diff --git a/driver_zodiac.c b/driver_zodiac.c
index 1da18bf4..2a0e367e 100644
--- a/driver_zodiac.c
+++ b/driver_zodiac.c
@@ -486,7 +486,6 @@ const struct gps_type_t driver_zodiac =
#ifdef TIMEHINT_ENABLE
.time_offset = zodiac_time_offset, /* compute NTO fudge factor */
#endif /* TIMEHINT_ENABLE */
- .minlength = 40, /* min packet length for chunked I/O */
};
/* *INDENT-ON* */
diff --git a/drivers.c b/drivers.c
index b5c898dc..0003ad11 100644
--- a/drivers.c
+++ b/drivers.c
@@ -16,8 +16,6 @@
#include "bits.h" /* for getbeu16(), to extract big-endian words */
#include "strfuncs.h"
-#define NMEA_MINLENGTH 16 /* minimum length of NMEA0183 packet */
-
ssize_t generic_get(struct gps_device_t *session)
{
return packet_get(session->gpsdata.gps_fd, &session->lexer);
@@ -104,7 +102,6 @@ const struct gps_type_t driver_unknown = {
#ifdef TIMEHINT_ENABLE
.time_offset = NULL, /* no method for NTP fudge factor */
#endif /* TIMEHINT_ENABLE */
- .minlength = 0, /* minimum packet length is unknown */
};
/* *INDENT-ON* */
@@ -275,7 +272,6 @@ const struct gps_type_t driver_nmea0183 = {
#ifdef TIMEHINT_ENABLE
.time_offset = NULL, /* no method for NTP fudge factor */
#endif /* TIMEHINT_ENABLE */
- .minlength = NMEA_MINLENGTH, /* min packet length for chunked I/O */
};
/* *INDENT-ON* */
@@ -378,7 +374,6 @@ const struct gps_type_t driver_garmin = {
#ifdef TIMEHINT_ENABLE
.time_offset = NULL, /* no method for NTP fudge factor */
#endif /* TIMEHINT_ENABLE */
- .minlength = NMEA_MINLENGTH, /* min packet length for chunked I/O */
};
/* *INDENT-ON* */
#endif /* GARMIN_ENABLE && NMEA_ENABLE */
@@ -442,7 +437,6 @@ const struct gps_type_t driver_ashtech = {
#ifdef TIMEHINT_ENABLE
.time_offset = NULL, /* no method for NTP fudge factor */
#endif /* TIMEHINT_ENABLE */
- .minlength = 0, /* minimum packet length is unknown */
};
/* *INDENT-ON* */
#endif /* ASHTECH_ENABLE */
@@ -495,7 +489,6 @@ const struct gps_type_t driver_fv18 = {
#ifdef TIMEHINT_ENABLE
.time_offset = NULL, /* no method for NTP fudge factor */
#endif /* TIMEHINT_ENABLE */
- .minlength = NMEA_MINLENGTH, /* use NMEA minimum length */
};
/* *INDENT-ON* */
#endif /* FV18_ENABLE */
@@ -551,7 +544,6 @@ const struct gps_type_t driver_gpsclock = {
#ifdef TIMEHINT_ENABLE
.time_offset = NULL, /* no method for NTP fudge factor */
#endif /* TIMEHINT_ENABLE */
- .minlength = NMEA_MINLENGTH, /* use NMEA minimum length */
};
/* *INDENT-ON* */
#endif /* GPSCLOCK_ENABLE */
@@ -608,7 +600,6 @@ static const struct gps_type_t driver_tripmate = {
#ifdef TIMEHINT_ENABLE
.time_offset = NULL, /* no method for NTP fudge factor */
#endif /* TIMEHINT_ENABLE */
- .minlength = NMEA_MINLENGTH, /* use NME0183 minimum langth */
};
/* *INDENT-ON* */
#endif /* TRIPMATE_ENABLE */
@@ -660,7 +651,6 @@ static const struct gps_type_t driver_earthmate = {
#endif /* CONTROLSEND_ENABLE */
#ifdef TIMEHINT_ENABLE
.time_offset = NULL, /* no method for NTP fudge factor */
- .minlength = 40, /* use Zodiac minimum langth */
#endif /* TIMEHINT_ENABLE */
};
/*@ -redef @*/
@@ -788,7 +778,6 @@ const struct gps_type_t driver_trueNorth = {
#ifdef TIMEHINT_ENABLE
.time_offset = NULL,
#endif /* TIMEHINT_ENABLE */
- .minlength = NMEA_MINLENGTH, /* use NME0183 minimum langth */
};
/* *INDENT-ON* */
#endif
@@ -869,7 +858,6 @@ static const struct gps_type_t driver_oceanServer = {
#ifdef TIMEHINT_ENABLE
.time_offset = NULL,
#endif /* TIMEHINT_ENABLE */
- .minlength = NMEA_MINLENGTH, /* use NME0183 minimum langth */
};
/* *INDENT-ON* */
#endif
@@ -938,7 +926,6 @@ static const struct gps_type_t driver_fury = {
#ifdef TIMEHINT_ENABLE
.time_offset = NULL,
#endif /* TIMEHINT_ENABLE */
- .minlength = NMEA_MINLENGTH, /* use NME0183 minimum langth */
};
/* *INDENT-ON* */
@@ -994,7 +981,6 @@ static const struct gps_type_t driver_rtcm104v2 = {
#ifdef TIMEHINT_ENABLE
.time_offset = NULL,
#endif /* TIMEHINT_ENABLE */
- .minlength = 0, /* raw I/O - could probably be tuned */
};
/* *INDENT-ON* */
#endif /* RTCM104V2_ENABLE */
@@ -1042,7 +1028,6 @@ static const struct gps_type_t driver_rtcm104v3 = {
#ifdef TIMEHINT_ENABLE
.time_offset = NULL,
#endif /* TIMEHINT_ENABLE */
- .minlength = 0, /* raw I/O - could probably be tuned */
};
/* *INDENT-ON* */
#endif /* RTCM104V3_ENABLE */
@@ -1079,7 +1064,6 @@ static const struct gps_type_t driver_garmintxt = {
#ifdef TIMEHINT_ENABLE
.time_offset = NULL,
#endif /* TIMEHINT_ENABLE */
- .minlength = 0, /* min packet length unknown */
};
/* *INDENT-ON* */
#endif /* GARMINTXT_ENABLE */
@@ -1176,7 +1160,6 @@ const struct gps_type_t driver_mtk3301 = {
#ifdef TIMEHINT_ENABLE
.time_offset = NULL,
#endif /* TIMEHINT_ENABLE */
- .minlength = NMEA_MINLENGTH, /* use NME0183 minimum langth */
};
/* *INDENT-ON* */
#endif /* MTK3301_ENABLE */
@@ -1420,7 +1403,6 @@ const struct gps_type_t driver_aivdm = {
#ifdef TIMEHINT_ENABLE
.time_offset = NULL, /* no NTP communication */
#endif /* TIMEHINT_ENABLE */
- .minlength = 23, /* minimum AIVDM packet length */
};
/* *INDENT-ON* */
#endif /* AIVDM_ENABLE */
@@ -1525,7 +1507,6 @@ const struct gps_type_t driver_json_passthrough = {
#ifdef TIMEHINT_ENABLE
.time_offset = NULL, /* no method for NTP fudge factor */
#endif /* TIMEHINT_ENABLE */
- .minlength = 43, /* minimum JSON packet length */
};
/* *INDENT-ON* */
diff --git a/gpsd.h-tail b/gpsd.h-tail
index edc8930f..8cdf1761 100644
--- a/gpsd.h-tail
+++ b/gpsd.h-tail
@@ -389,7 +389,6 @@ struct gps_type_t {
#ifdef TIMEHINT_ENABLE
/*@null@*/double (*time_offset)(struct gps_device_t *session);
#endif /* TIMEHINT_ENABLE */
- int minlength;
};
/*
@@ -824,7 +823,6 @@ extern void ntrip_report(struct gps_context_t *,
extern void gpsd_tty_init(struct gps_device_t *);
extern int gpsd_serial_open(struct gps_device_t *);
-extern void gpsd_optimize_io(struct gps_device_t *, const int, const bool);
extern bool gpsd_set_raw(struct gps_device_t *);
extern ssize_t gpsd_serial_write(struct gps_device_t *,
const char *, const size_t);
diff --git a/gpsdecode.c b/gpsdecode.c
index ece81d57..f31a59f6 100644
--- a/gpsdecode.c
+++ b/gpsdecode.c
@@ -621,7 +621,7 @@ static void decode(FILE *fpin, FILE*fpout)
break;
}
}
- printf("%s (%d): %u\n", np, i-1, (unsigned int)minima[i]);
+ printf("%s (%d): %d\n", np, i-1, (unsigned int)minima[i]);
}
}
}
diff --git a/libgpsd_core.c b/libgpsd_core.c
index 579d32e1..b9868bfa 100644
--- a/libgpsd_core.c
+++ b/libgpsd_core.c
@@ -248,9 +248,6 @@ int gpsd_switch_driver(struct gps_device_t *session, char *type_name)
"selecting %s driver...\n",
(*dp)->type_name);
gpsd_assert_sync(session);
- gpsd_optimize_io(session,
- (*dp)->minlength,
- TEXTUAL_PACKET_TYPE((*dp)->packet_type));
/*@i@*/ session->device_type = *dp;
session->driver_index = i;
#ifdef RECONFIGURE_ENABLE
diff --git a/serial.c b/serial.c
index 25333678..9bc74e13 100644
--- a/serial.c
+++ b/serial.c
@@ -535,7 +535,19 @@ int gpsd_serial_open(struct gps_device_t *session)
&session->ttyset_old, sizeof(session->ttyset));
/*
* Only block until we get at least one character, whatever the
- * third arg of read(2) says.
+ * third arg of read(2) says. According to
+ * http://stackoverflow.com/questions/20154157/termios-vmin-vtime-and-blocking-non-blocking-read-operations
+ * the VMIN setting may be a no-op because the tty was opened with
+ * O_NONBLOCK. Money quote:
+ *
+ * "When using select() with a file in non-blocking mode, you
+ * get an event for every byte that arrives. At high serial
+ * data rates, this hammers the CPU. It's better to use
+ * blocking mode with VMIN, so that select() waits for a
+ * block of data before firing an event, and VTIME to limit
+ * the delay, for blocks smaller than VMIN."
+ *
+ * Would that we could do the latter...
*/
/*@ ignore @*/
memset(session->ttyset.c_cc, 0, sizeof(session->ttyset.c_cc));
@@ -609,61 +621,6 @@ ssize_t gpsd_serial_write(struct gps_device_t * session,
return status;
}
-void gpsd_optimize_io(struct gps_device_t *session,
- int minlength, const bool textual UNUSED)
-/* optimize I/O mode depending on the minimum packet size */
-{
- /* bail out if this is not actually a tty */
- if (isatty(session->gpsdata.gps_fd) == 0)
- return;
-
-#ifdef __NetBSD__
- /*
- * Apparently NetBSD termios (at least on pty on netbsd-[56]) has
- * trouble with VMIN=n VTIME=1. Or reads are aftempted when no
- * bytes are present and none arrive, in which case read is
- * correct for waiting indefinitely. Until this is
- * debugged/fixed, avoid it, because even if it doesn't affect
- * actual operation (unknown) it's important to preserve
- * regression tests to allow bisecting for other bugs.
- * http://pubs.opengroup.org/onlinepubs/007908799/xbd/termios.html
- */
- minlength = 1;
-#endif
-
- /*
- * This is an optimization hack. The idea is to get away from
- * character-at-a-time I/O in order to slow down the rate at
- * which the main select loop spins (those calls eat power
- * noticeably in environments like Android phones and the
- * Raspberry Pi). We tell the tty layer to wait until it has
- * either accumulated characters corresponding to the minimum
- * possible length of a packet or timed out.
- *
- * For the moment, we do nothing with the textual flag. We'd like
- * to use it to set ICANON mode and let the kernel do all the line
- * buffering itself. The problem with this is that VTIME stops
- * working in ICANON mode, so a binary packet coming up the wire
- * would result in no further input being seen.
- */
- if (minlength > 1) {
- session->ttyset.c_cc[VMIN] = minlength;
- session->ttyset.c_cc[VTIME] = 1; /* 0.1 sec */
- } else {
- /* raw character-at-at-time I/O, no timeout */
- session->ttyset.c_cc[VMIN] = 1;
- session->ttyset.c_cc[VTIME] = 0;
- }
-
- if (tcsetattr(session->gpsdata.gps_fd, TCSANOW, &session->ttyset) != 0)
- return;
-
- gpsd_report(&session->context->errout, LOG_IO,
- "tty params optimized for min length %d of %s packets\n",
- minlength, textual ? "textual" : "binary");
-}
-
-
/*
* This constant controls how long the packet sniffer will spend looking
* for a packet leader before it gives up. It *must* be larger than