Esempio n. 1
0
INLINE int set_socket_async P2(int, fd, int, which)
{
#ifdef OLD_ULTRIX
    return fcntl(fd, F_SETFL, FASYNC);
#else
    return OS_socket_ioctl(fd, FIOASYNC, &which);
#endif
}
Esempio n. 2
0
INLINE int set_socket_nonblocking P2(int, fd, int, which)
{
#if !defined(OLD_ULTRIX) && !defined(_SEQUENT_)
    int result;
#endif

#ifdef OLD_ULTRIX
    if (which)
	return fcntl(fd, F_SETFL, FNDELAY);
    else
	return fcntl(fd, F_SETFL, FNBLOCK);
#else

#ifdef _SEQUENT_
    int flags = fcntl(fd, F_GETFL, 0);

    if (flags == -1)
	return (-1);
    if (which)
	flags |= O_NONBLOCK;
    else
	flags &= ~O_NONBLOCK;
    return fcntl(fd, F_SETFL, flags);
#else
    result = OS_socket_ioctl(fd, FIONBIO, &which);
    if (result == -1)
	debug_perror("set_socket_nonblocking: ioctl", 0);
#if 0
    /* boggle ... someone track down an errno for this */
    if (result == -1) {
	XXX("Try using cc instead of gcc to correct this error.\n");
    }
#endif
    return result;
#endif

#endif
}
Esempio n. 3
0
void conn_data_handler (int fd)
{
    int conn_index;
    int buf_index;
    int num_bytes;
    int msgtype;
    int leftover;
    char *buf;
    int res, msglen, expecting;
    long unread_bytes;

    if ((conn_index = index_by_fd(fd)) == -1) {
	fprintf(stderr, "conn_data_handler: invalid fd.\n");
	return;
    }
    DBG(("conn_data_handler: read on fd %d", fd));

    /* append new data to end of leftover data (if any) */
    leftover = all_conns[conn_index].leftover;
    buf = (char *) &all_conns[conn_index].buf[0];
    num_bytes = OS_socket_read(fd, buf + leftover, (IN_BUF_SIZE - 1) - leftover);

    switch (num_bytes) {
    case -1:
	switch (socket_errno) {
	case EWOULDBLOCK:
	    DBG(("conn_data_handler: read on fd %d: Operation would block.",
			fd));
	    break;
	default:
	    socket_perror("conn_data_handler: read", 0);
	    terminate(conn_index);
	    break;
	}
	break;
    case 0:
	if (all_conns[conn_index].state == CONN_CLOSED)
	    fprintf(stderr, "get_user_data: tried to read from closed fd.\n");
	terminate(conn_index);
	break;
    default:
	DBG(("conn_data_handler: read %d bytes on fd %d", num_bytes, fd));
	num_bytes += leftover;
	buf_index = 0;
	expecting = 0;
	while (num_bytes > sizeof(int) && buf_index < (IN_BUF_SIZE - 1)) {
	    /* get message type */
	    memcpy((char *) &msgtype, (char *) &buf[buf_index], sizeof(int));
	    DBG(("conn_data_handler: message type: %d", msgtype));

	    if (msgtype == NAMEBYIP) {
		if (buf[buf_index + sizeof(int)] == '\0') {
		    /* no data here...resync */
		    buf_index++;
		    num_bytes--;
		    continue;
		}
		if (expecting && num_bytes < expecting) {
		    /*
		     * message truncated...back up to DATALEN message; exit
		     * loop...and try again later
		     */
		    buf_index -= (sizeof(int) + sizeof(int));
		    num_bytes += (sizeof(int) + sizeof(int));
		    break;
		}
		res = name_by_ip(conn_index, &buf[buf_index]);
	    } else if (msgtype == IPBYNAME) {
		if (buf[buf_index + sizeof(int)] == '\0') {
		    /* no data here...resync */
		    buf_index++;
		    num_bytes--;
		    continue;
		}
		if (expecting && num_bytes < expecting) {
		    /*
		     * message truncated...back up to DATALEN message; exit
		     * loop...and try again later
		     */
		    buf_index -= (sizeof(int) + sizeof(int));
		    num_bytes += (sizeof(int) + sizeof(int));
		    break;
		}
		res = ip_by_name(conn_index, &buf[buf_index]);
	    } else if (msgtype == DATALEN) {
		if (num_bytes > (sizeof(int) + sizeof(int))) {
		    memcpy((char *) &expecting, (char *) &buf[buf_index + sizeof(int)], sizeof(int));
		    /*
		     * advance to next message
		     */
		    buf_index += (sizeof(int) + sizeof(int));
		    num_bytes -= (sizeof(int) + sizeof(int));
		    if (expecting > IN_BUF_SIZE || expecting <= 0) {
			fprintf(stderr, "conn_data_handler: bad data length %d\n", expecting);
			expecting = 0;
		    }
		    continue;
		} else {
		    /*
		     * not enough bytes...assume truncated; exit loop...we'll
		     * handle this message later
		     */
		    break;
		}
	    } else {
		fprintf(stderr, "conn_data_handler: unknown message type %08x\n", msgtype);
		/* advance through buffer */
		buf_index++;
		num_bytes--;
		continue;
	    }

	    msglen = (int) (sizeof(int) + strlen(&buf[buf_index + sizeof(int)]) +1);
	    if (res) {
		/*
		 * ok...advance to next message
		 */
		buf_index += msglen;
		num_bytes -= msglen;
	    } else if (msglen < num_bytes || (expecting && expecting == msglen)) {
		/*
		 * failed...
		 */

		/*
		 * this was a complete message...advance to the next one
		 */
		msglen = (int) (sizeof(int) + strlen(&buf[buf_index + sizeof(int)]) +1);
		buf_index += msglen;
		num_bytes -= msglen;
		expecting = 0;
	    }
	    else if (!OS_socket_ioctl(fd, FIONREAD, &unread_bytes) &&
		     unread_bytes > 0) {
		/*
		 * msglen == num_bytes could be a complete message... if
		 * there's unread data we'll assume it was truncated
		 */
		break;
	    } else {
		/*
		 * nothing more?  then discard message (it was the last one)
		 */
		buf_index = 0;
		num_bytes = 0;
		break;
	    }
	}

	/* keep track of leftover buffer contents */
	if (num_bytes && buf_index)
	    memmove(buf, &buf[buf_index], num_bytes);
	buf[num_bytes] = '\0';
	all_conns[conn_index].leftover = num_bytes;

	break;
    }
}