Changeset 47
- Timestamp:
- 06/30/08 17:33:55 (2 months ago)
- Files:
-
- trunk/libsipc/man/man3/sipc_recv_data.3 (modified) (1 diff)
- trunk/libsipc/src/Makefile (modified) (1 diff)
- trunk/libsipc/src/sipc.c (modified) (2 diffs)
- trunk/libsipc/src/sipc_mqueue.c (modified) (6 diffs)
- trunk/libsipc/src/sipc_shm.c (modified) (2 diffs)
- trunk/libsipc/tests/Makefile (modified) (2 diffs)
- trunk/libsipc/tests/mqueue.c (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/libsipc/man/man3/sipc_recv_data.3
r45 r47 24 24 .TP 25 25 .I len 26 Pointer to the total number of bytes received 26 Pointer to the total number of bytes received (which could be 0). 27 27 .PP 28 28 If the IPC channel is a message queue, \fBsipc_recv_data\fR() trunk/libsipc/src/Makefile
r44 r47 19 19 ln -sf $@ $(TARGET) 20 20 21 %.o: %.c 21 %.o: %.c sipc_internal.h 22 22 $(CC) $(AM_CFLAGS) $(CFLAGS) $(INCLUDEDIRS) -c -o $@ $< 23 23 trunk/libsipc/src/sipc.c
r46 r47 152 152 return -1; 153 153 } 154 if (msg_len < 0) { 155 errno = EINVAL; 156 return -1; 157 } 158 if (sipc->role != SIPC_SENDER) { 159 sipc_error(sipc, "sipc_send_data called without sender flag enabled in IPC structure\n"); 160 errno = EBADF; 161 return -1; 162 } 163 if (msg_len > sipc->data_size) { 164 sipc_error(sipc, "sipc_send_data: cannot send buffer of size %d, can only receive %zd\n", msg_len, sipc->data_size); 165 errno = ENOMEM; 166 return -1; 167 } 154 168 155 169 return sipc->funcs->sipc_send_data(sipc, msg_len); … … 158 172 int sipc_recv_data(sipc_t *sipc, char **data, int *len) 159 173 { 160 if (!sipc) 161 return -1; 174 if (data) 175 *data = NULL; /* Pointer to a buffer created here */ 176 if (len) 177 *len = 0; /* Bytes received so far */ 178 if (!sipc || !data || !len) { 179 errno = EINVAL; 180 return -1; 181 } 182 if (sipc->role != SIPC_RECEIVER) { 183 sipc_error(sipc, "sipc_recv_data called without receiver flag enabled in IPC structure\n"); 184 errno = EBADF; 185 return -1; 186 } 162 187 163 188 return sipc->funcs->sipc_recv_data(sipc, data, len); trunk/libsipc/src/sipc_mqueue.c
r46 r47 54 54 static int mqueue_send_msg_len(sipc_t *sipc, int msg_len); 55 55 static int mqueue_send_end_xmit(sipc_t *sipc); 56 static char *split_data(sipc_t *sipc, size_t packet_sz);57 56 static int is_msg_len(struct msgbuf *mbuf); 58 57 static int is_end_xmit(struct msgbuf *mbuf); 59 static int msg_done(sipc_t *sipc);60 static size_t next_packet_sz(int recv, int max_packet_sz, int msg_len);61 58 static size_t next_alloc_sz(int recv, int recv_sz, int max_packet_sz, int msg_len); 62 59 … … 142 139 int sipc_mqueue_send_data(sipc_t *sipc, int msg_len) 143 140 { 144 int max_packet_sz = SIPC_MQUEUE_MSG_SZ - sizeof(struct msgbuf);141 size_t max_packet_sz = SIPC_MQUEUE_MSG_SZ - sizeof(long); 145 142 int error = 0; 146 size_t packet_sz;147 char *packet = NULL;148 149 if (!sipc) {150 error = EINVAL;151 goto err;152 }153 if (sipc->role != SIPC_SENDER) {154 error = EINVAL;155 goto err;156 }157 143 158 144 struct msgbuf *mbuf = sipc->mbuf; 159 145 assert(mbuf); 160 146 memset(mbuf, 0, SIPC_MQUEUE_MSG_SZ); 161 sipc->msg_len = msg_len;162 147 if (mqueue_send_msg_len(sipc, msg_len) < 0) { 163 148 error = errno; … … 165 150 } 166 151 167 sipc->copied = 0; /* Reset copied data counter */ 168 do { 169 packet_sz = next_packet_sz(sipc->copied, max_packet_sz, msg_len); 170 171 if ((packet = split_data(sipc, packet_sz)) == NULL) { 172 error = errno; 173 sipc_error(sipc, "%s\n", "Unable to fragment message data"); 174 goto err; 175 } 176 177 bzero(mbuf->mtext, packet_sz); 152 size_t amount_written = 0; 153 while (amount_written < msg_len) { 154 size_t amount_to_write = msg_len - amount_written > max_packet_sz ? max_packet_sz : msg_len - amount_written; 155 178 156 mbuf->mtype = SIPC_DATA_READY; 179 memcpy(mbuf->mtext, packet, packet_sz);157 memcpy(mbuf->mtext, sipc->data + amount_written, amount_to_write); 180 158 181 159 /* Send the message */ 182 while (msgsnd(sipc->msqid, mbuf, packet_sz, 0) < 0) {160 while (msgsnd(sipc->msqid, mbuf, amount_to_write, 0) < 0) { 183 161 error = errno; 184 162 if (error != EINTR) { … … 187 165 } 188 166 } 189 free(packet);190 } while (!msg_done(sipc));167 amount_written += amount_to_write; 168 } 191 169 192 170 /* Send end of message marker */ … … 195 173 goto err; 196 174 } 197 sipc->msg_len = SIPC_MSGLEN_NOT_SET;198 175 return 0; 199 176 200 177 err: 201 free(packet);202 sipc->msg_len = SIPC_MSGLEN_NOT_SET;203 178 errno = error; 204 179 return -1; … … 434 409 } 435 410 436 /* Returns 1 if the message has been completely fragmented,437 * 0 otherwise. */438 static int msg_done(sipc_t *sipc)439 {440 return sipc->copied >= sipc->msg_len ? 1 : 0;441 }442 443 /* Splits data in sipc into a chunk the size of the maximum444 * allowed for a message in a message queue.445 * This function allocates space for the fragmented piece of data.446 * The caller is responsible for freeign this memory. */447 static char *split_data(sipc_t *sipc, size_t packet_sz)448 {449 size_t remaining = sipc->msg_len - sipc->copied;450 size_t len = remaining > packet_sz ? packet_sz : remaining;451 char *packet = calloc(1, len);452 if (!packet)453 return NULL;454 455 memcpy(packet, (sipc->data) + (sipc->copied), len);456 sipc->copied += len;457 458 return packet;459 }460 461 /* Determine the next packet's size.462 * A packet should not contain extra padding.463 * Returns the size of the next packet on success, -1 on failure. */464 static size_t next_packet_sz(int recv, int max_packet_sz, int msg_len)465 {466 if (recv < 0 || max_packet_sz <= 0 || msg_len <= 0)467 return -1;468 469 if (recv + max_packet_sz > msg_len)470 return msg_len - recv;471 else472 return max_packet_sz;473 474 }475 476 411 /* Determine how much memory to allocate for receiving a packet. 477 412 * A packet should not contain extra padding. trunk/libsipc/src/sipc_shm.c
r46 r47 161 161 { 162 162 int error; 163 if (!sipc) {164 errno = EINVAL;165 return -1;166 }167 163 168 164 /* Send a DATA_READY marker */ … … 204 200 int block; 205 201 206 if (data)207 *data = NULL; /* Pointer to a buffer created here */208 if (len)209 *len = 0; /* Bytes received so far */210 if (!sipc || !data || !len) {211 errno = EINVAL;212 return -1;213 }214 202 block = (sipc->non_blocking == 0 ? 1 : 0); 215 203 trunk/libsipc/tests/Makefile
r44 r47 1 1 TESTS = test_ipc ipc_creator ipc_destroyer 2 AM_CFLAGS = -I../include3 AM_LDFLAGS = -lsipc -lcunit -Wl,-rpath=$(TOP_BUILDDIR)/src -L$(TOP_BUILDDIR)/src2 AM_CFLAGS += -I../include 3 AM_LDFLAGS += -lsipc -lcunit -Wl,-rpath=$(TOP_BUILDDIR)/src -L$(TOP_BUILDDIR)/src 4 4 TOP_BUILDDIR := $(shell pwd)/.. 5 5 … … 22 22 -rm -rf $(TESTS) 23 23 24 .PHONY: all install test clean24 .PHONY: all install tests clean trunk/libsipc/tests/mqueue.c
r45 r47 284 284 free(data); 285 285 } 286 287 CU_ASSERT(sipc_recv_data(reader_ipc, &data, &len) == 0); 288 CU_ASSERT_PTR_NOT_NULL(data); 289 CU_ASSERT(len == 0); 290 free(data); 286 291 } 287 292 … … 312 317 CU_ASSERT(send_end_xmit(writer_ipc) == 0); 313 318 fclose(ifile); 319 320 /* Trying sending a zero-byte message */ 321 CU_ASSERT(sipc_send_data(writer_ipc, 0) == 0); 314 322 315 323 /* Cleanup handle here */
