aboutsummaryrefslogtreecommitdiffstats
path: root/meta/recipes-connectivity/gsm/files/0004-Handle-read-and-write-return-values.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-connectivity/gsm/files/0004-Handle-read-and-write-return-values.patch')
-rw-r--r--meta/recipes-connectivity/gsm/files/0004-Handle-read-and-write-return-values.patch176
1 files changed, 176 insertions, 0 deletions
diff --git a/meta/recipes-connectivity/gsm/files/0004-Handle-read-and-write-return-values.patch b/meta/recipes-connectivity/gsm/files/0004-Handle-read-and-write-return-values.patch
new file mode 100644
index 0000000000..f5e7a7902d
--- /dev/null
+++ b/meta/recipes-connectivity/gsm/files/0004-Handle-read-and-write-return-values.patch
@@ -0,0 +1,176 @@
+From 421b0fa14fefbd13a455c20380fecddda616b41a Mon Sep 17 00:00:00 2001
+From: Andrzej Zaborowski <balrog@zabor.org>
+Date: Wed, 19 Sep 2007 18:30:36 +0200
+Subject: [PATCH] Handle read() and write() return values.
+
+---
+ include/libgsmd/libgsmd.h | 3 +-
+ src/gsmd/usock.c | 38 ++++++++++++++++-----------
+ src/libgsmd/lgsm_internals.h | 2 +
+ src/libgsmd/libgsmd.c | 58 ++++++++++++++++++++++++++---------------
+ 4 files changed, 63 insertions(+), 38 deletions(-)
+
+diff --git a/include/libgsmd/libgsmd.h b/include/libgsmd/libgsmd.h
+index fc56890..db15aa9 100644
+--- a/include/libgsmd/libgsmd.h
++++ b/include/libgsmd/libgsmd.h
+@@ -65,6 +65,7 @@ extern int lgsm_subscriptions(struct lgsm_handle *lh, u_int32_t subscriptions);
+
+ extern struct gsmd_msg_hdr *lgsm_gmh_fill(int type, int subtype, int payload_len);
+ extern int lgsm_send(struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh);
+-extern int lgsm_handle_packet(struct lgsm_handle *lh, char *buf, int len);
++extern int lgsm_handle_packet(struct lgsm_handle *lh,
++ const char *buf, int len);
+
+ #endif
+diff --git a/src/gsmd/usock.c b/src/gsmd/usock.c
+index bac5f0c..2283600 100644
+--- a/src/gsmd/usock.c
++++ b/src/gsmd/usock.c
+@@ -1569,23 +1569,29 @@ static int gsmd_usock_user_cb(int fd, unsigned int what, void *data)
+ struct gsmd_ucmd *ucmd, *uctmp;
+ llist_for_each_entry_safe(ucmd, uctmp, &gu->finished_ucmds,
+ list) {
+- int rc;
+-
+- rc = write(fd, &ucmd->hdr, sizeof(ucmd->hdr) + ucmd->hdr.len);
+- if (rc < 0) {
+- DEBUGP("write return %d\n", rc);
+- return rc;
+- }
+- if (rc == 0) {
+- DEBUGP("write returns zero!!\n");
+- break;
++ const void *pos = &ucmd->hdr;
++ size_t len = sizeof(ucmd->hdr) + ucmd->hdr.len;
++
++ while (len) {
++ ssize_t rc;
++
++ rc = write(fd, pos, len);
++ if (rc < 0 && errno != EINTR) {
++ DEBUGP("write returned %s\n",
++ strerror(errno));
++ return rc;
++ }
++ if (rc == 0 && pos == &ucmd->hdr) {
++ DEBUGP("write returns zero!!\n");
++ return 0;
++ }
++ if (rc > 0) {
++ len -= rc;
++ pos += rc;
++ }
+ }
+- if (rc != sizeof(ucmd->hdr) + ucmd->hdr.len) {
+- DEBUGP("short write\n");
+- break;
+- }
+-
+- DEBUGP("successfully sent cmd %p to user %p, freeing\n", ucmd, gu);
++ DEBUGP("successfully sent cmd %p to user %p, "
++ "freeing\n", ucmd, gu);
+ llist_del(&ucmd->list);
+ talloc_free(ucmd);
+ }
+diff --git a/src/libgsmd/lgsm_internals.h b/src/libgsmd/lgsm_internals.h
+index c826723..f1b1a23 100644
+--- a/src/libgsmd/lgsm_internals.h
++++ b/src/libgsmd/lgsm_internals.h
+@@ -8,6 +8,8 @@ struct lgsm_handle {
+ int fd;
+ lgsm_msg_handler *handler[__NUM_GSMD_MSGS];
+ enum lgsm_netreg_state netreg_state;
++ char usock_fifo[1024];
++ int usock_len;
+ };
+
+ int lgsm_send(struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh);
+diff --git a/src/libgsmd/libgsmd.c b/src/libgsmd/libgsmd.c
+index 9906ea8..cc804ed 100644
+--- a/src/libgsmd/libgsmd.c
++++ b/src/libgsmd/libgsmd.c
+@@ -86,34 +86,37 @@ static int lgsm_open_backend(struct lgsm_handle *lh, const char *device)
+ }
+
+ /* handle a packet that was received on the gsmd socket */
+-int lgsm_handle_packet(struct lgsm_handle *lh, char *buf, int len)
++int lgsm_handle_packet(struct lgsm_handle *lh, const char *buf, int len)
+ {
+ struct gsmd_msg_hdr *gmh;
+ lgsm_msg_handler *handler;
+ int rc = 0;
+
+- while (len) {
+- if (len < sizeof(*gmh))
+- return -EINVAL;
+- gmh = (struct gsmd_msg_hdr *) buf;
+-
+- if (len - sizeof(*gmh) < gmh->len)
+- return -EINVAL;
+- len -= sizeof(*gmh) + gmh->len;
+- buf += sizeof(*gmh) + gmh->len;
+-
+- if (gmh->msg_type >= __NUM_GSMD_MSGS)
+- return -EINVAL;
+-
+- handler = lh->handler[gmh->msg_type];
++ if (lh->usock_len + len > sizeof(lh->usock_fifo))
++ return -ENOMEM;
+
+- if (handler)
++ memcpy(lh->usock_fifo + lh->usock_len, buf, len);
++ lh->usock_len += len;
++ gmh = (struct gsmd_msg_hdr *) lh->usock_fifo;
++ while (lh->usock_len >= sizeof(*gmh) &&
++ lh->usock_len >= sizeof(*gmh) + gmh->len) {
++ if (gmh->msg_type < __NUM_GSMD_MSGS &&
++ (handler = lh->handler[gmh->msg_type]))
+ rc |= handler(lh, gmh);
+- else
+- fprintf(stderr, "unable to handle packet type=%u\n",
+- gmh->msg_type);
++ else {
++ fprintf(stderr, "unable to handle packet "
++ "type=%u id=%u\n",
++ gmh->msg_type, gmh->id);
++ rc |= EINVAL;
++ }
++
++ lh->usock_len -= gmh->len + sizeof(*gmh);
++ memmove(lh->usock_fifo,
++ lh->usock_fifo + gmh->len + sizeof(*gmh),
++ lh->usock_len);
+ }
+- return rc;
++
++ return -rc;
+ }
+
+ int lgsm_register_handler(struct lgsm_handle *lh, int type, lgsm_msg_handler *handler)
+@@ -193,8 +196,21 @@ static u_int16_t next_msg_id;
+
+ int lgsm_send(struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh)
+ {
++ ssize_t rc;
++ size_t len = sizeof(*gmh) + gmh->len;
++ const void *pos = gmh;
++
+ gmh->id = next_msg_id++;
+- return send(lh->fd, (char *) gmh, sizeof(*gmh) + gmh->len, 0);
++ while (len) {
++ rc = send(lh->fd, pos, len, 0);
++ if (rc < 0 && errno != EINTR)
++ return -errno;
++ if (rc > 0) {
++ len -= rc;
++ pos += rc;
++ }
++ }
++ return 0;
+ }
+
+ struct gsmd_msg_hdr *lgsm_gmh_fill(int type, int subtype, int payload_len)
+--
+1.5.2.1
+