summaryrefslogtreecommitdiff
path: root/libgps_shm.c
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>2011-03-26 01:42:09 -0400
committerEric S. Raymond <esr@thyrsus.com>2011-03-26 01:42:09 -0400
commitde697118c1ee31edb5a779534368e81ae0d0d7fe (patch)
tree34f9dc3068e33b3b341e3018978af042e81912e8 /libgps_shm.c
parent2f229c53d7d16961b6ecfd2bb99e1c29e0a81715 (diff)
downloadgpsd-de697118c1ee31edb5a779534368e81ae0d0d7fe.tar.gz
First cut at read side of shared-memory exporter.
Untested, probably buggy. All regression tests pass.
Diffstat (limited to 'libgps_shm.c')
-rw-r--r--libgps_shm.c75
1 files changed, 75 insertions, 0 deletions
diff --git a/libgps_shm.c b/libgps_shm.c
new file mode 100644
index 00000000..daf0f632
--- /dev/null
+++ b/libgps_shm.c
@@ -0,0 +1,75 @@
+/****************************************************************************
+
+NAME
+ libgps_shm.c - reasder access to shared-memory export
+
+DESCRIPTION
+ This is a very lightweight alternative to JSON-over-sockets. Clients
+won't be able to filter by device, and won't get device activation/deactivation
+notifications. But both client and daemon will avoid all the marshalling and
+unmarshalling overhead.
+
+PERMISSIONS
+ This file is Copyright (c) 2010 by the GPSD project
+ BSD terms apply: see the file COPYING in the distribution root for details.
+
+***************************************************************************/
+#include <stddef.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+
+#include "gpsd.h"
+
+#ifdef SHM_EXPORT_ENABLE
+
+int gps_shm_open(/*@out@*/struct gps_data_t *gpsdata)
+/* open a shared-memory connection to the daemon */
+{
+ int shmid;
+
+ gpsdata->privdata = NULL;
+ shmid = shmget((key_t)GPSD_KEY, sizeof(struct gps_data_t), 0);
+ if (shmid == -1) {
+ /* daemon isn't running or failed to create shared segment */
+ return -1;
+ }
+ gpsdata->privdata = shmat(shmid, 0, 0);
+ if ((int)(long)gpsdata->privdata == -1) {
+ /* attach failed for sume unknown reason */
+ return -2;
+ }
+ return 0;
+}
+
+int gps_shm_read(struct gps_data_t *gpsdata)
+/* read an update from the shared-memory segment */
+{
+ if (gpsdata->privdata == NULL)
+ return -1;
+ else
+ {
+ int before, after;
+ struct shmexport_t *shared = (struct shmexport_t *)gpsdata->privdata;
+
+ before = shared->bookend1;
+ (void)memcpy((void *)gpsdata,
+ (void *)&shared->gpsdata,
+ sizeof(struct gps_data_t));
+ after = shared->bookend2;
+ /*@i1@*/gpsdata->privdata = shared;
+ return (before == after) ? 0 : -1;
+ }
+}
+
+void gps_shm_close(struct gps_data_t *gpsdata)
+{
+ if (gpsdata->privdata != NULL)
+ (void)shmdt((const void *)gpsdata->privdata);
+}
+
+#endif /* SHM_EXPORT_ENABLE */
+
+/* end */