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 }
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 }
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; } }