예제 #1
0
/*
 * Peek at the full contents of a message buffer without marking any
 * data as read. `seqp' should point to an unsigned integer that
 * msgbuf_peekbytes() can use to retain state between calls so that
 * the whole message buffer can be read in multiple short reads.
 * To initialise this variable to the start of the message buffer,
 * call msgbuf_peekbytes() with a NULL `buf' parameter.
 *
 * Returns the number of characters that were placed in `buf'.
 */
int
msgbuf_peekbytes(struct msgbuf *mbp, char *buf, int buflen, u_int *seqp)
{
    u_int len, pos, wseq;

    mtx_lock_spin(&mbp->msg_lock);

    if (buf == NULL) {
        /* Just initialise *seqp. */
        *seqp = MSGBUF_SEQNORM(mbp, mbp->msg_wseq - mbp->msg_size);
        mtx_unlock_spin(&mbp->msg_lock);
        return (0);
    }

    wseq = mbp->msg_wseq;
    len = MSGBUF_SEQSUB(mbp, wseq, *seqp);
    if (len == 0) {
        mtx_unlock_spin(&mbp->msg_lock);
        return (0);
    }
    if (len > mbp->msg_size) {
        *seqp = MSGBUF_SEQNORM(mbp, wseq - mbp->msg_size);
        len = mbp->msg_size;
    }
    pos = MSGBUF_SEQ_TO_POS(mbp, *seqp);
    len = min(len, mbp->msg_size - pos);
    len = min(len, (u_int)buflen);
    bcopy(&mbp->msg_ptr[MSGBUF_SEQ_TO_POS(mbp, *seqp)], buf, len);
    *seqp = MSGBUF_SEQNORM(mbp, *seqp + len);

    mtx_unlock_spin(&mbp->msg_lock);

    return (len);
}
예제 #2
0
/*
 * Read and mark as read a number of characters from a message buffer.
 * Returns the number of characters that were placed in `buf'.
 */
int
msgbuf_getbytes(struct msgbuf *mbp, char *buf, int buflen)
{
    u_int len, pos, wseq;

    mtx_lock_spin(&mbp->msg_lock);

    wseq = mbp->msg_wseq;
    len = MSGBUF_SEQSUB(mbp, wseq, mbp->msg_rseq);
    if (len == 0) {
        mtx_unlock_spin(&mbp->msg_lock);
        return (0);
    }
    if (len > mbp->msg_size) {
        mbp->msg_rseq = MSGBUF_SEQNORM(mbp, wseq - mbp->msg_size);
        len = mbp->msg_size;
    }
    pos = MSGBUF_SEQ_TO_POS(mbp, mbp->msg_rseq);
    len = min(len, mbp->msg_size - pos);
    len = min(len, (u_int)buflen);

    bcopy(&mbp->msg_ptr[pos], buf, len);
    mbp->msg_rseq = MSGBUF_SEQNORM(mbp, mbp->msg_rseq + len);

    mtx_unlock_spin(&mbp->msg_lock);

    return (len);
}
예제 #3
0
/*
 * Get a count of the number of unread characters in the message buffer.
 */
int
msgbuf_getcount(struct msgbuf *mbp)
{
    u_int len;

    len = MSGBUF_SEQSUB(mbp, mbp->msg_wseq, mbp->msg_rseq);
    if (len > mbp->msg_size)
        len = mbp->msg_size;
    return (len);
}
/*
 * Read and mark as read a character from a message buffer.
 * Returns the character, or -1 if no characters are available.
 */
int
msgbuf_getchar(struct msgbuf *mbp)
{
	u_int len, wseq;
	int c;

	wseq = mbp->msg_wseq;
	len = MSGBUF_SEQSUB(mbp, wseq, mbp->msg_rseq);
	if (len == 0)
		return (-1);
	if (len > mbp->msg_size)
		mbp->msg_rseq = MSGBUF_SEQNORM(mbp, wseq - mbp->msg_size);
	c = (u_char)mbp->msg_ptr[MSGBUF_SEQ_TO_POS(mbp, mbp->msg_rseq)];
	mbp->msg_rseq = MSGBUF_SEQNORM(mbp, mbp->msg_rseq + 1);
	return (c);
}