summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--SConstruct8
-rw-r--r--gpsd.h13
-rw-r--r--libgps_sock.c62
-rw-r--r--netlib.c40
-rw-r--r--os_compat.c5
-rw-r--r--test_libgps.c3
6 files changed, 119 insertions, 12 deletions
diff --git a/SConstruct b/SConstruct
index 1de0fa75..c780bcbb 100644
--- a/SConstruct
+++ b/SConstruct
@@ -750,9 +750,15 @@ else:
announce("You do not have the endian.h header file. RTCM V2 support disabled.")
env["rtcm104v2"] = False
+ for hdr in ("sys/un", "sys/socket", "sys/select", "netdb", "netinet/in", "netinet/ip", "arpa/inet", "termios", "winsock2"):
+ if config.CheckHeader(hdr + ".h"):
+ confdefs.append("#define HAVE_%s_H 1\n" % hdr.replace("/","_").upper())
+ else:
+ confdefs.append("/* #undef HAVE_%s_H */\n" % hdr.replace("/","_").upper())
+
# check function after libraries, because some function require libraries
# for example clock_gettime() require librt on Linux glibc < 2.17
- for f in ("daemon", "strlcpy", "strlcat", "clock_gettime", "strptime", "gmtime_r" ):
+ for f in ("daemon", "strlcpy", "strlcat", "clock_gettime", "strptime", "gmtime_r", "inet_ntop", "fcntl"):
if config.CheckFunc(f):
confdefs.append("#define HAVE_%s 1\n" % f.upper())
else:
diff --git a/gpsd.h b/gpsd.h
index b3dc3c97..50aa759a 100644
--- a/gpsd.h
+++ b/gpsd.h
@@ -17,11 +17,16 @@ extern "C" {
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
+#include "gpsd_config.h"
+#ifdef HAVE_TERMIOS_H
#include <termios.h>
+#endif
+#ifdef HAVE_WINSOCK2_H
+#include <winsock2.h> /* for fd_set */
+#endif
#include <time.h> /* for time_t */
#include "gps.h"
-#include "gpsd_config.h"
#include "os_compat.h"
/*
@@ -361,11 +366,13 @@ struct gps_type_t {
void (*init_query)(struct gps_device_t *session);
void (*event_hook)(struct gps_device_t *session, event_t event);
#ifdef RECONFIGURE_ENABLE
+#ifdef HAVE_TERMIOS_H
bool (*speed_switcher)(struct gps_device_t *session,
speed_t speed, char parity, int stopbits);
void (*mode_switcher)(struct gps_device_t *session, int mode);
bool (*rate_switcher)(struct gps_device_t *session, double rate);
double min_cycle;
+#endif /* HAVE_TERMIOS_H */
#endif /* RECONFIGURE_ENABLE */
#ifdef CONTROLSEND_ENABLE
ssize_t (*control_send)(struct gps_device_t *session, char *buf, size_t buflen);
@@ -472,7 +479,9 @@ struct gps_device_t {
sourcetype_t sourcetype;
servicetype_t servicetype;
int mode;
+#ifdef HAVE_TERMIOS_H
struct termios ttyset, ttyset_old;
+#endif
#ifndef FIXED_PORT_SPEED
unsigned int baudindex;
#endif /* FIXED_PORT_SPEED */
@@ -822,9 +831,11 @@ extern ssize_t gpsd_serial_write(struct gps_device_t *,
const char *, const size_t);
extern bool gpsd_next_hunt_setting(struct gps_device_t *);
extern int gpsd_switch_driver(struct gps_device_t *, char *);
+#ifdef HAVE_TERMIOS_H
extern void gpsd_set_speed(struct gps_device_t *, speed_t, char, unsigned int);
extern speed_t gpsd_get_speed(const struct gps_device_t *);
extern speed_t gpsd_get_speed_old(const struct gps_device_t *);
+#endif /* HAVE_TERMIOS_H */
extern int gpsd_get_stopbits(const struct gps_device_t *);
extern char gpsd_get_parity(const struct gps_device_t *);
extern void gpsd_assert_sync(struct gps_device_t *);
diff --git a/libgps_sock.c b/libgps_sock.c
index ea04b8cd..31f73f5c 100644
--- a/libgps_sock.c
+++ b/libgps_sock.c
@@ -16,11 +16,19 @@
#include <sys/time.h> /* expected to have a select(2) prototype a la SuS */
#include <sys/types.h>
#include <sys/stat.h>
+#include "gpsd_config.h"
+#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
+#endif /* HAVE_SYS_SELECT_H */
#include <unistd.h>
#ifndef USE_QT
+#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
+#endif /* HAVE_SYS_SOCKET_H */
+#ifdef HAVE_WINSOCK2_H
+#include <winsock2.h>
+#endif /* HAVE_WINSOCK2_H */
#else
#include <QTcpSocket>
#endif /* USE_QT */
@@ -43,6 +51,33 @@ struct privdata_t
#endif /* LIBGPS_DEBUG */
};
+#ifdef HAVE_WINSOCK2_H
+static bool need_init = TRUE;
+static bool need_finish = TRUE;
+
+static bool windows_init(void)
+/* Ensure socket networking is initialized for Windows. */
+{
+ WSADATA wsadata;
+ /* request access to Windows Sockets API version 2.2 */
+ int res = WSAStartup(MAKEWORD(2, 2), &wsadata);
+ if (res != 0) {
+ libgps_debug_trace((DEBUG_CALLS, "WSAStartup returns error %d\n", res));
+ }
+ return (res == 0);
+}
+
+static bool windows_finish(void)
+/* Shutdown Windows Sockets. */
+{
+ int res = WSACleanup();
+ if (res != 0) {
+ libgps_debug_trace((DEBUG_CALLS, "WSACleanup returns error %d\n", res));
+ }
+ return (res == 0);
+}
+#endif /* HAVE_WINSOCK2_H */
+
int gps_sock_open(const char *host, const char *port,
struct gps_data_t *gpsdata)
{
@@ -54,6 +89,11 @@ int gps_sock_open(const char *host, const char *port,
libgps_debug_trace((DEBUG_CALLS, "gps_sock_open(%s, %s)\n", host, port));
#ifndef USE_QT
+#ifdef HAVE_WINSOCK2_H
+ if (need_init) {
+ need_init != windows_init();
+ }
+#endif
if ((gpsdata->gps_fd =
netlib_connectsock(AF_UNSPEC, host, port, "tcp")) < 0) {
errno = gpsdata->gps_fd;
@@ -62,7 +102,7 @@ int gps_sock_open(const char *host, const char *port,
}
else
libgps_debug_trace((DEBUG_CALLS, "netlib_connectsock() returns socket on fd %d\n", gpsdata->gps_fd));
-#else
+#else /* HAVE_WINSOCK2_H */
QTcpSocket *sock = new QTcpSocket();
gpsdata->gps_fd = sock;
sock->connectToHost(host, QString(port).toInt());
@@ -119,7 +159,14 @@ int gps_sock_close(struct gps_data_t *gpsdata)
gpsdata->privdata = NULL;
#ifndef USE_QT
int status;
+#ifdef HAVE_WINSOCK2_H
+ status = closesocket(gpsdata->gps_fd);
+ if (need_finish) {
+ need_finish != windows_finish();
+ }
+#else
status = close(gpsdata->gps_fd);
+#endif /* HAVE_WINSOCK2_H */
gpsdata->gps_fd = -1;
return status;
#else
@@ -160,7 +207,9 @@ int gps_sock_read(struct gps_data_t *gpsdata)
sizeof(PRIVATE(gpsdata)->buffer) -
PRIVATE(gpsdata)->waiting);
#endif
-
+#ifdef HAVE_WINSOCK2_H
+ int wserr = WSAGetLastError();
+#endif /* HAVE_WINSOCK2_H */
/* if we just received data from the socket, it's in the buffer */
if (status > -1)
PRIVATE(gpsdata)->waiting += status;
@@ -175,9 +224,14 @@ int gps_sock_read(struct gps_data_t *gpsdata)
return -1;
#ifndef USE_QT
/* count transient errors as success, we'll retry later */
+#ifdef HAVE_WINSOCK2_H
+ else if (wserr == WSAEINTR || wserr == WSAEWOULDBLOCK)
+ return 0;
+#else
else if (errno == EINTR || errno == EAGAIN
|| errno == EWOULDBLOCK)
return 0;
+#endif /* HAVE_WINSOCK2_H */
#endif
/* hard error return of -1, pass it along */
else
@@ -245,7 +299,11 @@ int gps_sock_send(struct gps_data_t *gpsdata, const char *buf)
/* send a command to the gpsd instance */
{
#ifndef USE_QT
+#ifdef HAVE_WINSOCK2_H
+ if (send(gpsdata->gps_fd, buf, strlen(buf), 0) == (ssize_t) strlen(buf))
+#else
if (write(gpsdata->gps_fd, buf, strlen(buf)) == (ssize_t) strlen(buf))
+#endif /* HAVE_WINSOCK2_H */
return 0;
else
return -1;
diff --git a/netlib.c b/netlib.c
index c8969382..2939454d 100644
--- a/netlib.c
+++ b/netlib.c
@@ -3,21 +3,38 @@
* BSD terms apply: see the file COPYING in the distribution root for details.
*/
+#include "gpsd_config.h"
#include <string.h>
#include <fcntl.h>
+#ifdef HAVE_NETDB_H
#include <netdb.h>
+#endif /* HAVE_NETDB_H */
#ifndef AF_UNSPEC
#include <sys/types.h>
#include <sys/stat.h>
+#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
+#endif /* HAVE_SYS_SOCKET_H */
#endif /* AF_UNSPEC */
+#ifdef HAVE_SYS_UN_H
#include <sys/un.h>
+#endif /* HAVE_SYS_UN_H */
#ifndef INADDR_ANY
+#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
+#endif /* HAVE_NETINET_IN_H */
#endif /* INADDR_ANY */
+#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h> /* for htons() and friends */
+#endif /* HAVE_ARPA_INET_H */
#include <unistd.h>
+#ifdef HAVE_NETINET_IN_H
#include <netinet/ip.h>
+#endif /* HAVE_NETINET_IN_H */
+#ifdef HAVE_WINSOCK2_H
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#endif
#include "gpsd.h"
#include "sockaddr.h"
@@ -97,7 +114,11 @@ socket_t netlib_connectsock(int af, const char *host, const char *service,
}
if (!BAD_SOCKET(s)) {
- (void)close(s);
+#ifdef HAVE_WINSOCK2_H
+ (void)closesocket(s);
+#else
+ (void)close(s);
+#endif
}
}
freeaddrinfo(result);
@@ -126,8 +147,12 @@ socket_t netlib_connectsock(int af, const char *host, const char *service,
#endif
/* set socket to noblocking */
+#ifdef HAVE_FCNTL
(void)fcntl(s, F_SETFL, fcntl(s, F_GETFL) | O_NONBLOCK);
-
+#elif defined(HAVE_WINSOCK2_H)
+ u_long one1 = 1;
+ (void)ioctlsocket(s, FIONBIO, &one1);
+#endif
return s;
}
@@ -155,6 +180,7 @@ const char *netlib_errstr(const int err)
socket_t netlib_localsocket(const char *sockfile, int socktype)
/* acquire a connection to an existing Unix-domain socket */
{
+#ifdef HAVE_SYS_UN_H
int sock;
if ((sock = socket(AF_UNIX, socktype, 0)) < 0) {
@@ -175,16 +201,19 @@ socket_t netlib_localsocket(const char *sockfile, int socktype)
return sock;
}
+#else
+ return -1;
+#endif /* HAVE_SYS_UN_H */
}
char *netlib_sock2ip(socket_t fd)
/* retrieve the IP address corresponding to a socket */
{
+ static char ip[INET6_ADDRSTRLEN];
+ int r = 1;
+#ifdef HAVE_INET_NTOP
sockaddr_t fsin;
socklen_t alen = (socklen_t) sizeof(fsin);
- static char ip[INET6_ADDRSTRLEN];
- int r;
-
r = getpeername(fd, &(fsin.sa), &alen);
if (r == 0) {
switch (fsin.sa.sa_family) {
@@ -203,6 +232,7 @@ char *netlib_sock2ip(socket_t fd)
return ip;
}
}
+#endif /* HAVE_INET_NTOP */
if (r != 0) {
(void)strlcpy(ip, "<unknown>", sizeof(ip));
}
diff --git a/os_compat.c b/os_compat.c
index b110f4ba..dafbb7a4 100644
--- a/os_compat.c
+++ b/os_compat.c
@@ -45,7 +45,8 @@ int clock_gettime(clockid_t clk_id, struct timespec *ts)
/* End of clock_gettime section */
#ifndef HAVE_DAEMON
-
+#ifndef HAVE_WINSOCK2_H
+/* No daemon() provided for Windows as not currently needed */
/* Simulate Linux/BSD daemon() on platforms that don't have it */
#include <stdlib.h>
@@ -90,7 +91,7 @@ int os_daemon(int nochdir, int noclose)
/* coverity[leaked_handle] Intentional handle duplication */
return 0;
}
-
+#endif /* HAVE_WINSOCK2_H */
#else /* HAVE_DAEMON */
#ifdef __linux__
diff --git a/test_libgps.c b/test_libgps.c
index 91dd65b3..933beba0 100644
--- a/test_libgps.c
+++ b/test_libgps.c
@@ -43,7 +43,9 @@ int main(int argc, char *argv[])
#endif
(void)signal(SIGSEGV, onsig);
+#ifdef SIGBUS
(void)signal(SIGBUS, onsig);
+#endif
while ((option = getopt(argc, argv, "bf:hsD:?")) != -1) {
switch (option) {
@@ -144,7 +146,6 @@ int main(int argc, char *argv[])
}
(void)gps_close(&collect);
}
-
return 0;
}