summaryrefslogtreecommitdiffstats
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 @@
1From 421b0fa14fefbd13a455c20380fecddda616b41a Mon Sep 17 00:00:00 2001
2From: Andrzej Zaborowski <balrog@zabor.org>
3Date: Wed, 19 Sep 2007 18:30:36 +0200
4Subject: [PATCH] Handle read() and write() return values.
5
6---
7 include/libgsmd/libgsmd.h | 3 +-
8 src/gsmd/usock.c | 38 ++++++++++++++++-----------
9 src/libgsmd/lgsm_internals.h | 2 +
10 src/libgsmd/libgsmd.c | 58 ++++++++++++++++++++++++++---------------
11 4 files changed, 63 insertions(+), 38 deletions(-)
12
13diff --git a/include/libgsmd/libgsmd.h b/include/libgsmd/libgsmd.h
14index fc56890..db15aa9 100644
15--- a/include/libgsmd/libgsmd.h
16+++ b/include/libgsmd/libgsmd.h
17@@ -65,6 +65,7 @@ extern int lgsm_subscriptions(struct lgsm_handle *lh, u_int32_t subscriptions);
18
19 extern struct gsmd_msg_hdr *lgsm_gmh_fill(int type, int subtype, int payload_len);
20 extern int lgsm_send(struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh);
21-extern int lgsm_handle_packet(struct lgsm_handle *lh, char *buf, int len);
22+extern int lgsm_handle_packet(struct lgsm_handle *lh,
23+ const char *buf, int len);
24
25 #endif
26diff --git a/src/gsmd/usock.c b/src/gsmd/usock.c
27index bac5f0c..2283600 100644
28--- a/src/gsmd/usock.c
29+++ b/src/gsmd/usock.c
30@@ -1569,23 +1569,29 @@ static int gsmd_usock_user_cb(int fd, unsigned int what, void *data)
31 struct gsmd_ucmd *ucmd, *uctmp;
32 llist_for_each_entry_safe(ucmd, uctmp, &gu->finished_ucmds,
33 list) {
34- int rc;
35-
36- rc = write(fd, &ucmd->hdr, sizeof(ucmd->hdr) + ucmd->hdr.len);
37- if (rc < 0) {
38- DEBUGP("write return %d\n", rc);
39- return rc;
40- }
41- if (rc == 0) {
42- DEBUGP("write returns zero!!\n");
43- break;
44+ const void *pos = &ucmd->hdr;
45+ size_t len = sizeof(ucmd->hdr) + ucmd->hdr.len;
46+
47+ while (len) {
48+ ssize_t rc;
49+
50+ rc = write(fd, pos, len);
51+ if (rc < 0 && errno != EINTR) {
52+ DEBUGP("write returned %s\n",
53+ strerror(errno));
54+ return rc;
55+ }
56+ if (rc == 0 && pos == &ucmd->hdr) {
57+ DEBUGP("write returns zero!!\n");
58+ return 0;
59+ }
60+ if (rc > 0) {
61+ len -= rc;
62+ pos += rc;
63+ }
64 }
65- if (rc != sizeof(ucmd->hdr) + ucmd->hdr.len) {
66- DEBUGP("short write\n");
67- break;
68- }
69-
70- DEBUGP("successfully sent cmd %p to user %p, freeing\n", ucmd, gu);
71+ DEBUGP("successfully sent cmd %p to user %p, "
72+ "freeing\n", ucmd, gu);
73 llist_del(&ucmd->list);
74 talloc_free(ucmd);
75 }
76diff --git a/src/libgsmd/lgsm_internals.h b/src/libgsmd/lgsm_internals.h
77index c826723..f1b1a23 100644
78--- a/src/libgsmd/lgsm_internals.h
79+++ b/src/libgsmd/lgsm_internals.h
80@@ -8,6 +8,8 @@ struct lgsm_handle {
81 int fd;
82 lgsm_msg_handler *handler[__NUM_GSMD_MSGS];
83 enum lgsm_netreg_state netreg_state;
84+ char usock_fifo[1024];
85+ int usock_len;
86 };
87
88 int lgsm_send(struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh);
89diff --git a/src/libgsmd/libgsmd.c b/src/libgsmd/libgsmd.c
90index 9906ea8..cc804ed 100644
91--- a/src/libgsmd/libgsmd.c
92+++ b/src/libgsmd/libgsmd.c
93@@ -86,34 +86,37 @@ static int lgsm_open_backend(struct lgsm_handle *lh, const char *device)
94 }
95
96 /* handle a packet that was received on the gsmd socket */
97-int lgsm_handle_packet(struct lgsm_handle *lh, char *buf, int len)
98+int lgsm_handle_packet(struct lgsm_handle *lh, const char *buf, int len)
99 {
100 struct gsmd_msg_hdr *gmh;
101 lgsm_msg_handler *handler;
102 int rc = 0;
103
104- while (len) {
105- if (len < sizeof(*gmh))
106- return -EINVAL;
107- gmh = (struct gsmd_msg_hdr *) buf;
108-
109- if (len - sizeof(*gmh) < gmh->len)
110- return -EINVAL;
111- len -= sizeof(*gmh) + gmh->len;
112- buf += sizeof(*gmh) + gmh->len;
113-
114- if (gmh->msg_type >= __NUM_GSMD_MSGS)
115- return -EINVAL;
116-
117- handler = lh->handler[gmh->msg_type];
118+ if (lh->usock_len + len > sizeof(lh->usock_fifo))
119+ return -ENOMEM;
120
121- if (handler)
122+ memcpy(lh->usock_fifo + lh->usock_len, buf, len);
123+ lh->usock_len += len;
124+ gmh = (struct gsmd_msg_hdr *) lh->usock_fifo;
125+ while (lh->usock_len >= sizeof(*gmh) &&
126+ lh->usock_len >= sizeof(*gmh) + gmh->len) {
127+ if (gmh->msg_type < __NUM_GSMD_MSGS &&
128+ (handler = lh->handler[gmh->msg_type]))
129 rc |= handler(lh, gmh);
130- else
131- fprintf(stderr, "unable to handle packet type=%u\n",
132- gmh->msg_type);
133+ else {
134+ fprintf(stderr, "unable to handle packet "
135+ "type=%u id=%u\n",
136+ gmh->msg_type, gmh->id);
137+ rc |= EINVAL;
138+ }
139+
140+ lh->usock_len -= gmh->len + sizeof(*gmh);
141+ memmove(lh->usock_fifo,
142+ lh->usock_fifo + gmh->len + sizeof(*gmh),
143+ lh->usock_len);
144 }
145- return rc;
146+
147+ return -rc;
148 }
149
150 int lgsm_register_handler(struct lgsm_handle *lh, int type, lgsm_msg_handler *handler)
151@@ -193,8 +196,21 @@ static u_int16_t next_msg_id;
152
153 int lgsm_send(struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh)
154 {
155+ ssize_t rc;
156+ size_t len = sizeof(*gmh) + gmh->len;
157+ const void *pos = gmh;
158+
159 gmh->id = next_msg_id++;
160- return send(lh->fd, (char *) gmh, sizeof(*gmh) + gmh->len, 0);
161+ while (len) {
162+ rc = send(lh->fd, pos, len, 0);
163+ if (rc < 0 && errno != EINTR)
164+ return -errno;
165+ if (rc > 0) {
166+ len -= rc;
167+ pos += rc;
168+ }
169+ }
170+ return 0;
171 }
172
173 struct gsmd_msg_hdr *lgsm_gmh_fill(int type, int subtype, int payload_len)
174--
1751.5.2.1
176