libixp

git clone git://oldgit.suckless.org/libixp/
Log | Files | Refs | LICENSE

transport.c (2351B)


      1 /* Copyright ©2007-2010 Kris Maglione <maglione.k at Gmail>
      2  * See LICENSE file for license details.
      3  */
      4 #include <errno.h>
      5 #include <fcntl.h>
      6 #include <stdio.h>
      7 #include <stdlib.h>
      8 #include <string.h>
      9 #include <sys/stat.h>
     10 #include <sys/socket.h>
     11 #include <sys/un.h>
     12 #include <unistd.h>
     13 #include "ixp_local.h"
     14 
     15 static int
     16 mread(int fd, IxpMsg *msg, uint count) {
     17 	int r, n;
     18 
     19 	n = msg->end - msg->pos;
     20 	if(n <= 0) {
     21 		werrstr("buffer full");
     22 		return -1;
     23 	}
     24 	if(n > count)
     25 		n = count;
     26 
     27 	r = thread->read(fd, msg->pos, n);
     28 	if(r > 0)
     29 		msg->pos += r;
     30 	return r;
     31 }
     32 
     33 static int
     34 readn(int fd, IxpMsg *msg, uint count) {
     35 	uint num;
     36 	int r;
     37 
     38 	num = count;
     39 	while(num > 0) {
     40 		r = mread(fd, msg, num);
     41 		if(r == -1 && errno == EINTR)
     42 			continue;
     43 		if(r == 0) {
     44 			werrstr("broken pipe: %s", ixp_errbuf());
     45 			return count - num;
     46 		}
     47 		num -= r;
     48 	}
     49 	return count - num;
     50 }
     51 
     52 /**
     53  * Function: ixp_sendmsg
     54  * Function: ixp_recvmsg
     55  *
     56  * These functions read and write messages to and from the given
     57  * file descriptors.
     58  *
     59  * ixp_sendmsg writes the data at P<msg>->pos upto P<msg>->end.
     60  * If the call returns non-zero, all data is assured to have
     61  * been written.
     62  *
     63  * ixp_recvmsg first reads a 32 bit, little-endian length from
     64  * P<fd> and then reads a message of that length (including the
     65  * 4 byte size specifier) into the buffer at P<msg>->data, so
     66  * long as the size is less than P<msg>->size.
     67  *
     68  * Returns:
     69  *	These functions return the number of bytes read or
     70  *	written, or 0 on error. Errors are stored in
     71  *	F<ixp_errbuf>.
     72  */
     73 uint
     74 ixp_sendmsg(int fd, IxpMsg *msg) {
     75 	int r;
     76 
     77 	msg->pos = msg->data;
     78 	while(msg->pos < msg->end) {
     79 		r = thread->write(fd, msg->pos, msg->end - msg->pos);
     80 		if(r < 1) {
     81 			if(errno == EINTR)
     82 				continue;
     83 			werrstr("broken pipe: %s", ixp_errbuf());
     84 			return 0;
     85 		}
     86 		msg->pos += r;
     87 	}
     88 	return msg->pos - msg->data;
     89 }
     90 
     91 uint
     92 ixp_recvmsg(int fd, IxpMsg *msg) {
     93 	enum { SSize = 4 };
     94 	uint32_t msize, size;
     95 
     96 	msg->mode = MsgUnpack;
     97 	msg->pos = msg->data;
     98 	msg->end = msg->data + msg->size;
     99 	if(readn(fd, msg, SSize) != SSize)
    100 		return 0;
    101 
    102 	msg->pos = msg->data;
    103 	ixp_pu32(msg, &msize);
    104 
    105 	size = msize - SSize;
    106 	if(size >= msg->end - msg->pos) {
    107 		werrstr("message too large");
    108 		return 0;
    109 	}
    110 	if(readn(fd, msg, size) != size) {
    111 		werrstr("message incomplete");
    112 		return 0;
    113 	}
    114 
    115 	msg->end = msg->pos;
    116 	return msize;
    117 }
    118