예제 #1
0
파일: sock.c 프로젝트: sd-eblana/bawx
int	socketWrite(int sid, char *buf, int bufsize)
{
	socket_t	*sp;
	ringq_t		*rq;
	int			len, bytesWritten, room;

	a_assert(buf);
	a_assert(bufsize >= 0);

	if ((sp = socketPtr(sid)) == NULL) {
		return -1;
	}

/*
 *	Loop adding as much data to the output ringq as we can absorb. Initiate a 
 *	flush when the ringq is too full and continue. Block in socketFlush if the
 *	socket is in blocking mode.
 */
	rq = &sp->outBuf;
	for (bytesWritten = 0; bufsize > 0; ) {
		if ((room = ringqPutBlkMax(rq)) == 0) {
			if (socketFlush(sid) < 0) {
				return -1;
			}
			if ((room = ringqPutBlkMax(rq)) == 0) {
				if (sp->flags & SOCKET_BLOCK) {
#if (defined (WIN) || defined (CE))
					int		errCode;
					if (! socketWaitForEvent(sp,  FD_WRITE | SOCKET_WRITABLE,
						&errCode)) {
						return -1;
					}
#endif
					continue;
				}
				break;
			}
			continue;
		}
		len = min(room, bufsize);
		ringqPutBlk(rq, (unsigned char *) buf, len);
		bytesWritten += len;
		bufsize -= len;
		buf += len;
	}
	return bytesWritten;
}
예제 #2
0
int ringqInsertcA(ringq_t *rq, char c)
{
	a_assert(rq);
	a_assert(rq->buflen == (rq->endbuf - rq->buf));

	if (ringqPutBlkMax(rq) == 0 && !ringqGrow(rq)) {
		return -1;
	}
	if (rq->servp <= rq->buf) {
		rq->servp = rq->endbuf;
	}
	*--rq->servp = (unsigned char) c;
	return 0;
}
예제 #3
0
int ringqPutcA(ringq_t *rq, char c)
{
	a_assert(rq);
	a_assert(rq->buflen == (rq->endbuf - rq->buf));

	if (ringqPutBlkMax(rq) == 0 && !ringqGrow(rq)) {
		return -1;
	}

	*rq->endp++ = (unsigned char) c;
	if (rq->endp >= rq->endbuf) {
		rq->endp = rq->buf;
	}
	return 0;
}
예제 #4
0
int ringqInsertc(ringq_t *rq, char_t c)
{
	char_t *cp;

	a_assert(rq);
	a_assert(rq->buflen == (rq->endbuf - rq->buf));

	if (ringqPutBlkMax(rq) < (int) sizeof(char_t) && !ringqGrow(rq)) {
		return -1;
	}
	if (rq->servp <= rq->buf) {
		rq->servp = rq->endbuf;
	}
	cp = (char_t*) rq->servp;
	*--cp = (char_t) c;
	rq->servp = (unsigned char *) cp;
	return 0;
}
예제 #5
0
int ringqPutc(ringq_t *rq, char_t c)
{
	char_t *cp;

	a_assert(rq);
	a_assert(rq->buflen == (rq->endbuf - rq->buf));

	if ((ringqPutBlkMax(rq) < (int) sizeof(char_t)) && !ringqGrow(rq)) {
		return -1;
	}

	cp = (char_t*) rq->endp;
	*cp++ = (char_t) c;
	rq->endp = (unsigned char *) cp;
	if (rq->endp >= rq->endbuf) {
		rq->endp = rq->buf;
	}
	return 0;
}
예제 #6
0
파일: sock.c 프로젝트: sd-eblana/bawx
int	socketRead(int sid, char *buf, int bufsize)
{
	socket_t	*sp;
	ringq_t		*rq;
	int			len, room, errCode, bytesRead;

	a_assert(buf);
	a_assert(bufsize > 0);

	if ((sp = socketPtr(sid)) == NULL) {
		return -1;
	}

	if (sp->flags & SOCKET_EOF) {
		return 0;
	}

	rq = &sp->inBuf;
	for (bytesRead = 0; bufsize > 0; ) {
		len = min(ringqLen(rq), bufsize);
		if (len <= 0) {
/*
 *			if blocking mode and already have data, exit now or it may block
 *			forever.
 */
			if ((sp->flags & SOCKET_BLOCK) &&
				(bytesRead > 0)) {
				break;
			}
/*
 *			This flush is critical for readers of datagram packets. If the
 *			buffer is not big enough to read the whole datagram in one hit,
 *			the recvfrom call will fail. 
 */
			ringqFlush(rq);
			room = ringqPutBlkMax(rq);
			len = socketGetInput(sid, (char *) rq->endp, room, &errCode);
			if (len < 0) {
				if (errCode == EWOULDBLOCK) {
					if ((sp->flags & SOCKET_BLOCK) &&
						(bytesRead ==  0)) {
						continue;
					}
					if (bytesRead >= 0) {
						return bytesRead;
					}
				}
				return -1;

			} else if (len == 0) {
/*
 *				If bytesRead is 0, this is EOF since socketRead should never
 *				be called unless there is data yet to be read.  Set the flag.  
 *				Then pass back the number of bytes read.
 */
				if (bytesRead == 0) {
					sp->flags |= SOCKET_EOF;
				}
				return bytesRead;
			}
			ringqPutBlkAdj(rq, len);
			len = min(len, bufsize);
		}
		memcpy(&buf[bytesRead], rq->servp, len);
		ringqGetBlkAdj(rq, len);
		bufsize -= len;
		bytesRead += len;
	}
	return bytesRead;
}