void select_call::prepare_to_poll() { /* * Create copies of all sets and zero out the originals. * This is needed because polling might be successful. * * If the read set is zero, use the local copy every time. * This is OK because it will hold only the CQ, and wait() * clears the CQ from the set after orig_select() call. * * m_readfds is non-NULL here because there are offloaded sockets. */ // copy sets, and zero out the originals if (m_readfds) { FD_COPY(&m_orig_readfds, m_readfds, m_nfds); FD_ZERO(m_readfds, m_nfds); } if (m_writefds) { FD_COPY(&m_orig_writefds, m_writefds, m_nfds); FD_ZERO(m_writefds, m_nfds); } if (m_exceptfds) { FD_COPY(&m_orig_exceptfds, m_exceptfds, m_nfds); FD_ZERO(m_exceptfds, m_nfds); } m_b_run_prepare_to_poll = true; }
int listening ( void ) { debug(); FD_COPY ( & listeningToRead, & listenersCanRead ); FD_COPY ( & listeningToWrite, & listenersCanWrite ); FD_COPY ( & listeningForFailure, & listenersHaveFailed ); //struct timeval timeout; //timeout.tv_sec = 2; int result = select ( getHighestFileDescriptor () + 1, & listenersCanRead, & listenersCanWrite, & listenersHaveFailed, NULL //& timeout ); if ( result < 0 ) { error ( __FILE__ ); stillListening = false; } for ( int listener = 0; listener < numberOfListeners; listener++ ) recognize ( listener ); return stillListening; }
int SockSelect (double timeout, char *flags) { int r; fd_set readfds; struct timeval tv, *tvp; #ifdef USE_BCOPY if (bcmp (&readable, &zero, sizeof (zero))) return 1; #else if (memcmp (&readable, &zero, sizeof (zero))) return 1; #endif if (timeout < 0.0) tvp = 0; else { tv.tv_sec = timeout; tv.tv_usec = (timeout - tv.tv_sec) * 1e+6; tvp = &tv; } FD_COPY (&fds, &readfds); r = select (max_sd + 1, &readfds, (fd_set *) 0, (fd_set *) 0, tvp); return r; }
void netClientReadBinary(netClient *client, void *base, int *cnt, int timeout) { fd_set selectSet; fd_set copySet; FD_ZERO(&selectSet); FD_SET(client->m_socket, &selectSet); int bufferSize = *cnt; *cnt = 0; FD_COPY(&selectSet, ©Set); struct timeval to; to.tv_sec = timeout; to.tv_usec = 0; int sel = select(client->m_socket+1, ©Set, NULL, NULL, &to); if (sel == -1) errorRaise(error_net, "Network error while waiting for data"); if (sel != 0) { *cnt = read(client->m_socket, base, bufferSize); //printf(" [%i/%i] ", bufferSize, *cnt); } if (*cnt == -1) errorRaise(error_net, "Network error while reading data"); }
bool select_call::wait_os(bool zero_timeout) { timeval to, *pto = NULL; timespec to_pselect, *pto_pselect = NULL; /* Avner: I put it in comment, because this logic is wrong // optimization: do not call os select if ALL fds are excluded // extend check to write/except fds if (m_rfd_count == m_n_exclude_fds) return; */ if (zero_timeout) { to.tv_sec = to.tv_usec = 0; pto = &to; } else { pto = m_timeout; } // Restore original sets if (m_b_run_prepare_to_poll) { if (m_readfds) FD_COPY(m_readfds, &m_os_rfds, m_nfds); if (m_writefds) FD_COPY(m_writefds, &m_os_wfds, m_nfds); if (m_exceptfds)FD_COPY(m_exceptfds, &m_orig_exceptfds, m_nfds); } __log_func("calling os select: %d", m_nfds); if (m_sigmask) { if (pto) { to_pselect.tv_sec = pto->tv_sec; to_pselect.tv_nsec = pto->tv_usec * 1000; pto_pselect = &to_pselect; } m_n_all_ready_fds = orig_os_api.pselect(m_nfds, m_readfds, m_writefds, m_exceptfds, pto_pselect, m_sigmask); } else { m_n_all_ready_fds = orig_os_api.select(m_nfds, m_readfds, m_writefds, m_exceptfds, pto); } if (m_n_all_ready_fds < 0) { vma_throw_object(io_mux_call::io_error); } if (m_n_all_ready_fds > 0) { __log_func("wait_os() returned with %d", m_n_all_ready_fds); } return false; // No cq_fd in select() event }
bool writePipeState(const int iSeconds = 0, const int iMicroSeconds = 0) { if (fdPipe[PIPE_STATE] == -1) return false; struct timeval tvTimeout; // timeout value for the select tvTimeout.tv_sec = iSeconds; tvTimeout.tv_usec = 0; FDSET_GROUP fdsCopy; // FDSET_GROUP is a struct taken from boinc/lib/network.h FD_COPY(&(fdsWatch.read_fds), &(fdsCopy.read_fds)); FD_COPY(&(fdsWatch.write_fds), &(fdsCopy.write_fds)); FD_COPY(&(fdsWatch.exc_fds), &(fdsCopy.exc_fds)); fdsCopy.max_fd = fdsWatch.max_fd; // write the results to the sensor pipe, i.e. if sensor was found or not if (FD_ISSET(fdPipe[PIPE_STATE], &fdsWatch.write_fds)) { if (select(fdsCopy.max_fd+1, NULL, &(fdsCopy.write_fds), NULL, iSeconds > 0 || iMicroSeconds > 0 ? &tvTimeout : NULL) < 0) { // check the write fs (PIPE_STATE) fprintf(stderr, "writePipeState Level 0\n"); return false; } // which file descriptors are ready to be read from? if (FD_ISSET(fdPipe[PIPE_STATE], &fdsCopy.write_fds)) { // file is ready to be written to // now write this sensor information int retval = write(fdPipe[PIPE_STATE], tsm, sizeof(CQCNUSBState)); if (retval < 0) { // pipe error fprintf(stderr, "writePipeState Level 1\n"); return false; } else if (!retval) { //pipe has been closed fprintf(stderr, "writePipeState Level 2\n"); return false; } //else { // bytes were written to the pipe OK //} } else { // something wrong, just return fprintf(stderr, "writePipeState Level 3\n"); return false; } } return true; // must have written OK }
void run_clt(char **av) { t_env e; if ((e.my_sock = create_clt(av[1], ft_atoi(av[2]))) != -1) { init_clt(&e); while (my_exit(1, NULL) != 1) { FD_COPY(&e.fd_read, &e.fd_read_cpy); FD_COPY(&e.fd_write, &e.fd_write_cpy); do_select(&e); check_actions(&e); FD_ZERO(&e.fd_read_cpy); FD_ZERO(&e.fd_write_cpy); } close(e.my_sock); } }
bool readPipeSensor(const int iSeconds = 0, const int iMicroSeconds = 0) { if (fdPipe[PIPE_SENSOR] == -1) return false; struct timeval tvTimeout; // timeout value for the select tvTimeout.tv_sec = iSeconds; tvTimeout.tv_usec = iMicroSeconds; FDSET_GROUP fdsCopy; // FDSET_GROUP is a struct taken from boinc/lib/network.h FD_COPY(&(fdsWatch.read_fds), &(fdsCopy.read_fds)); FD_COPY(&(fdsWatch.write_fds), &(fdsCopy.write_fds)); FD_COPY(&(fdsWatch.exc_fds), &(fdsCopy.exc_fds)); fdsCopy.max_fd = fdsWatch.max_fd; // write the results to the sensor pipe, i.e. if sensor was found or not if (FD_ISSET(fdPipe[PIPE_SENSOR], &fdsWatch.read_fds)) { if (select(fdsCopy.max_fd+1, &(fdsCopy.read_fds), NULL, NULL, iSeconds > 0 || iMicroSeconds > 0 ? &tvTimeout : NULL) < 0) { // check the write fs (PIPE_STATE) fprintf(stderr, "readPipeSensor Level 0\n"); return false; } // which file descriptors are ready to be read from? if (FD_ISSET(fdPipe[PIPE_SENSOR], &fdsCopy.read_fds)) { //file is ready to be read from int retval = read(fdPipe[PIPE_SENSOR], tsm, sizeof(CQCNUSBSensor)); if (retval < 0) { // pipe error fprintf(stderr, "readPipeSensor Level 1\n"); return false; } else if (!retval) { //pipe has been closed //remove the closed pipe from the set fprintf(stderr, "readPipeSensor Level 2\n"); return false; } } else { // something wrong, just return fprintf(stderr, "readPipeSensor Level 3\n"); return false; } } return true; // must have read OK }
void Reactor::check_selects() { fd_set read_filedescriptors; fd_set write_filedescriptors; fd_set error_filedescriptors; FD_COPY(&this->read_filedescriptors, &read_filedescriptors); FD_COPY(&this->write_filedescriptors, &write_filedescriptors); FD_COPY(&this->error_filedescriptors, &error_filedescriptors); timeval timeout; timeout.tv_sec = 0; timeout.tv_usec = select_timeval * 1000000; if (select(0, &read_filedescriptors, &write_filedescriptors, &error_filedescriptors, &timeout) > 0) { } }
bool mainLoop(int argc, char **argv) { const char *port = PORT; int backlog = BACKLOG; int bufferSize = BUFFER_SIZE; bool interactive = INTERACTIVE; args_param_t args_param_list[] = { {"-p", &port, argsString }, {"--port", &port, argsString }, {"-b", &backlog, argsInteger }, {"--backlog", &backlog, argsInteger }, {"-B", &bufferSize, argsInteger }, {"--buffer", &bufferSize, argsInteger }, {"-i", &interactive, argsBoolTrue }, {"--interactive", &interactive, argsBoolTrue }, {"-d", &interactive, argsBoolFalse }, {"--daemon", &interactive, argsBoolFalse }, ARGS_DONE }; argsProcess(argc, argv, args_param_list); int socket = -1; fd_set socketSet; bool success = true; success = success && socketOpen(port, backlog, &socket); success = success && socketSetInitialize(socket, &socketSet, interactive); if (success) { infof("Message buffer size set to %d.", bufferSize); } // main loop int maxSocket = socket; success = success && protocolInit(socket, &socketSet, maxSocket, bufferSize); bool done = !success; // skip loop on error while (!done) { fd_set readSocketSet; FD_COPY(&socketSet, &readSocketSet); success = success && socketSelect(maxSocket, &readSocketSet); for (int s = 0; !done && s <= maxSocket; s++) { if (FD_ISSET(s, &readSocketSet)) { if (s == socket) { socketConnectionNew(s, &maxSocket, &socketSet, bufferSize); // failure is not terminal } else if (STDIN_FILENO == s) { // system control done = localControl(s, &socketSet, maxSocket, bufferSize); } else { // existing connection protocolUpdate(s, &socketSet, maxSocket, bufferSize); // failure is not terminal } } } done = done || !success; } protocolCleanup(socket, &socketSet, maxSocket, bufferSize); // always close(socket); return done; }
int main(int argc, char *argv[]) { int err; int nfds; int socketfd; db_t db; db_option_t option; fd_set readfds; fd_set writefds; char *dbfilename; char *idxfilename; struct addrinfo hints, *ai, *p; if (argc == 2) { dbfilename = argv[1]; idxfilename = NULL; } else if (argc != 3) { dbfilename = argv[1]; idxfilename = argv[2]; } else { fprintf(stderr, "usage: %s dbfile [indexfile]\n", argv[0]); return 0; } memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; if ((err = getaddrinfo(NULL, PORT, &hints, &ai)) != 0) { fprintf(stderr, "db-server: getaddrinfo: %s\n", gai_strerror(err)); exit(1); } for (p = ai; p != NULL; p = p->ai_next) { int optval = 1; socketfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol); if (socketfd == -1) { fprintf(stderr, "db-server: socket: %s\n", gai_strerror(err)); continue; } if (fcntl(socketfd, F_SETFL, O_NONBLOCK) == -1) { fprintf(stderr, "db-server: fcntl NONBLOCK: %s\n", strerror(errno)); continue; } if (setsockopt(socketfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) == -1) { fprintf(stderr, "db-server: setsockopt REUSEADDR: %s\n", strerror(errno)); continue; } if (bind(socketfd, p->ai_addr, p->ai_addrlen) < 0) { fprintf(stderr, "db-server: bind: %s\n", strerror(errno)); close(socketfd); continue; } break; } if (p == NULL) { fprintf(stderr, "db-server: failed to bind: %s\n", PORT); exit(1); } freeaddrinfo(ai); option.table = 256; option.bucket = 256; option.rdonly = 0; if (db_open(&db, dbfilename, idxfilename, &option) != DB_OK) { fprintf(stderr, "db-server: open db %s failed\n", dbfilename); exit(0); } if (listen(socketfd, 32) == -1) { fprintf(stderr, "db-server: listen: %s\n", strerror(errno)); exit(1); } FD_ZERO(&readfds); FD_ZERO(&writefds); nfds = socketfd; FD_SET(socketfd, &readfds); inbuf = malloc(INBUF_LEN); outbuf = malloc(OUTBUF_LEN); valbuf = malloc(VALBUF_LEN); for (;;) { int n; int fd; fd_set readfds_; fd_set writefds_; FD_ZERO(&readfds_); FD_ZERO(&writefds_); #ifdef LINUX memcpy(&readfds_, &readfds, sizeof(readfds)); memcpy(&writefds_, &writefds, sizeof(writefds)); #else FD_COPY(&readfds, &readfds_); FD_COPY(&writefds, &writefds_); #endif if ((n = select(nfds + 1, &readfds_, &writefds_, NULL, NULL)) == -1) { fprintf(stderr, "db-server: select: %s\n", strerror(errno)); exit(1); } for (fd = 0; fd <= nfds && n > 0; fd++) { if (FD_ISSET(fd, &writefds_)) { n--; handle_write(fd, &readfds, &writefds); } if (FD_ISSET(fd, &readfds_)) { n--; if (fd == socketfd) { int acceptfd; acceptfd = handle_accept(fd, &readfds, &writefds); if (acceptfd > nfds) { nfds = acceptfd; } } else { err = handle_read(fd, &db, &readfds, &writefds); if (err == -1 && fd >= nfds) { nfds = fd; while (FD_ISSET(nfds, &readfds) == 0 && FD_ISSET(nfds, &writefds) == 0) { nfds--; } } } } } } free(inbuf); free(outbuf); free(valbuf); return 0; }
int main (int argc,char *argv[]) { int sockfd, n, newsockfd, childpid, servlen,fin, i, tab[FD_SETSIZE], nbfd, maxfd, sockcli; struct sockaddr_in serv_addr, cli_addr; socklen_t clilen; fd_set rset, pset; /* Verifier le nombre de paramètre en entrée */ if (argc != 2){ usage(); exit(1);} /* * Ouvrir une socket (a TCP socket) */ if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) <0) { perror("servmulti : Probleme socket\n"); exit (2); } /* * Lier l'adresse locale à la socket */ memset( (char*) &serv_addr,0, sizeof(serv_addr) ); serv_addr.sin_family = PF_INET; serv_addr.sin_addr.s_addr = htonl (INADDR_ANY); serv_addr.sin_port = htons(atoi(argv[1])); maxfd = sockfd+1; if (bind(sockfd,(struct sockaddr *)&serv_addr, sizeof(serv_addr) ) <0) { perror ("servmulti : erreur bind\n"); exit (1); } /* Paramètrer le nombre de connexion "pending" */ if (listen(sockfd, SOMAXCONN) <0) { perror ("servmulti : erreur listen\n"); exit (1); } for(i = 0; i < FD_SETSIZE; i++){ tab[i] = -1; } FD_ZERO(&rset); FD_ZERO(&pset); FD_SET(sockfd, &rset); for (;;) { FD_COPY(&rset,&pset); nbfd = select(maxfd, &pset, NULL, NULL, NULL); if (nbfd < 0){ perror("servmulti : erreur select"); } if(FD_ISSET(sockfd, &pset)){ /*Tentative de connection*/ clilen = sizeof(cli_addr); newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); if (newsockfd < 0) { perror("servmulti : erreur accept\n"); exit (1); } } i = 0; while((i < FD_SETSIZE) && (tab[i] >= 0)) i ++; if( i == FD_SETSIZE) exit(1); tab[i] = newsockfd; FD_SET(newsockfd, &rset); if(newsockfd >= maxfd){ maxfd = newsockfd + 1; } i= 0; while((nbfd > 0) && (i < FD_SETSIZE)){ if(((sockcli = tab[i]))>= 0 && (FD_ISSET(sockcli, &pset))){ if(str_echo(sockcli) == 0){ close(sockcli); tab[i] = -1; FD_CLR(sockcli, &rset); } nbfd --; } i++; } } }
void ZSocketWatcher::pRun() { ZGuardMtx guard(fMtx); for (;;) { if (fSet.empty()) { // Nothing pending, wait 100ms in case something else comes along. fCnd.WaitFor(fMtx, 0.1); if (fSet.empty()) { // Still nothing pending, exit thread. fThreadRunning = false; break; } } else { fd_set readSet; FD_ZERO(&readSet); int largest = 0; foreachi (ii, fSet) { const int theFD = ii->first; if (largest < theFD) largest = theFD; FD_SET(ii->first, &readSet); } fd_set exceptSet; FD_COPY(&readSet, &exceptSet); struct timeval timeout; timeout.tv_sec = 1; timeout.tv_usec = 0; guard.Release(); int count = ::select(largest + 1, &readSet, nullptr, &exceptSet, &timeout); guard.Acquire(); if (count < 1) { // Didn't get any continue; } // Gather the callables set<ZRef<ZCallable_Void> > toCall; for (int fd = 1; fd <= largest; ++fd) { if (FD_ISSET(fd, &readSet)) { --count; if (FD_ISSET(fd, &exceptSet)) --count; } else if (FD_ISSET(fd, &exceptSet)) --count; else continue; const Set_t::iterator iterBegin = fSet.lower_bound(Pair_t(fd, null)); Set_t::iterator iterEnd = iterBegin; const Set_t::iterator SetEnd = fSet.end(); while (iterEnd->first == fd and iterEnd != SetEnd) { toCall.insert(iterEnd->second); ++iterEnd; } fSet.erase(iterBegin, iterEnd); if (count <= 0) break; } guard.Release(); foreachi (ii, toCall) { try { (*ii)->Call(); } catch (...) {} } guard.Acquire(); } } }
int main (int argc, char *argv[]) { int i=0; struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_addr.s_addr = inet_addr("127.0.0.1"); for(i=0;i<2;i++){ s[i] = socket(AF_INET, SOCK_STREAM, 0); addr.sin_port = htons(8080+i); fcntl(s[i], F_SETFL, O_NONBLOCK); int res = connect(s[i], (struct sockaddr*)&addr, sizeof(addr)); if(res != -1){ printf("Connect failed.\n"); fflush(stdout); exit(1); } FD_SET(s[i],&readset); FD_SET(s[i],&writeset); FD_SET(s[i],&exceptionset); } while(1){ FD_COPY(&readset,&readset1); FD_COPY(&writeset,&writeset1); FD_COPY(&readset,&readset1); int rdy = select(FD_SETSIZE,&readset1,&writeset1,&exceptionset1,0); for(i=0;i<2;i++){ if(FD_ISSET(s[i],&readset1)) { char buf[2048]; int rec_count = recv(s[i],buf,255,0); printf("Readset for port %d---=%d bytes read\n", 8080+i, rec_count); if(rec_count==-1){ shutdown(s[i],SHUT_RDWR); close(s[i]); FD_CLR(s[i],&readset); FD_CLR(s[i],&writeset); FD_CLR(s[i],&exceptionset); printf("Connection closed.\n"); continue; } } if(FD_ISSET(s[i],&writeset1)) { printf("Writeset for port %d\n", 8080+i); int status=0; char buf[2048]="Ritesh is the god of programming"; status = send(s[i],buf,strlen(buf)+1,0); if(status < 0) printf("xxxxWriteset for port %d, send status = %d\n", 8080+i, status); printf("Writeset for port %d, send status = %d\n", 8080+i, status); } if(FD_ISSET(s[i],&exceptionset1)) { printf("Exceptionset for port %d\n", 8080+i); } } } }/* main */
/* * Called initially after the process is forked. * This handles the initial error from process being emitted to stderr and * also handles the password prompt from ssh. */ static int js_initial_read (js_session_t *jsp, time_t secs, long usecs) { struct timeval tmo = { secs, usecs }; fd_set rfds, xfds; int sin = jsp->js_stdin, serr = jsp->js_stderr, smax, rc; int askpassfd = jsp->js_askpassfd ?: jsio_askpass_socket; do { smax = MAX(sin, serr); if (askpassfd >= 0) smax = MAX(smax, askpassfd); FD_ZERO(&rfds); FD_SET(sin, &rfds); if (serr >= 0) FD_SET(serr, &rfds); if (askpassfd >= 0) FD_SET(askpassfd, &rfds); FD_COPY(&rfds, &xfds); rc = select(smax + 1, &rfds, NULL, &xfds, &tmo); if (rc < 0) { if (errno == EINTR) continue; jsio_trace("error from rpc session: %m"); return -1; } if (rc == 0) { if (secs) jsio_trace("timeout from rpc session"); return -1; } if (serr >= 0 && (FD_ISSET(serr, &rfds) || FD_ISSET(serr, &xfds))) { char buf[BUFSIZ]; rc = read(serr, buf, sizeof(buf) - 1); if (rc > 0) { buf[sizeof(buf) - 1] = '\0'; jsio_trace("error from rpc session: %s", buf); } } if (askpassfd >= 0 && FD_ISSET(askpassfd, &rfds)) { if (askpassfd == jsio_askpass_socket) { askpassfd = js_ssh_askpass_accept(jsp); } else { js_ssh_askpass(jsp, askpassfd); askpassfd = jsio_askpass_socket; } } } while (!FD_ISSET(sin, &rfds)); return 0; }
int main(int argc, char **argv) { int port; if(argc==2) { port=atoi(argv[1]); } setlinebuf(stdout); int server_sock = socket(AF_INET, SOCK_STREAM, 0); if(server_sock < 0) { perror("Creating socket failed: "); exit(1); } struct sockaddr_in addr; // internet socket address data structure addr.sin_family = AF_INET; addr.sin_port = htons(port); // byte order is significant addr.sin_addr.s_addr = INADDR_ANY; // listen to all interfaces int res = bind(server_sock, (struct sockaddr*)&addr, sizeof(addr)); if(res < 0) { perror("Error binding to port"); exit(1); } int yes=1; if (setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { perror("setsockopt"); exit(1); } /* workaround for funny OS X bug - need to start listening without select */ res=fcntl(server_sock, F_SETFL, O_NONBLOCK); if(res<0) { perror("fcntl"); } if (listen (server_sock, 1) < 0) { perror ("listen"); exit(1); } fcntl(server_sock, F_SETFL, 0); /* initializing data structure for select call */ fd_set readset; FD_ZERO(&readset); FD_SET(server_sock,&readset); while(1) { fd_set rdyset; FD_COPY(&readset,&rdyset); int rdy = select(FD_SETSIZE,&rdyset,0,0,0); /* if the server_sock has a new connection coming in, accept it */ if(FD_ISSET(server_sock,&rdyset)) { int sock; struct sockaddr_in remote_addr; unsigned int socklen = sizeof(remote_addr); sock = accept(server_sock, (struct sockaddr*)&remote_addr, &socklen); if(res < 0) { perror("Error accepting connection"); exit(1); } /* allocate and initialize new client state */ struct client_state *state= (struct client_state*)malloc(sizeof(struct client_state)); state->next=clients; if(clients) clients->prev=state; state->prev=0; state->message_count=0; clients=state; state->socket=sock; client_count++; // added sprintf(state->name,"Client %d",client_count); printf("Got connection (%s)\n",state->name); // added /* add new socket to fd_set for select */ FD_SET(sock,&readset); } /* if any of the active clients are ready to deliver a message, read it and print it */ struct client_state *clstate = clients; while(clstate) { if(FD_ISSET(clstate->socket,&rdyset)) { char buf[255]; memset(buf,0,255); int rec_count = recv(clstate->socket,buf,255,0); if(rec_count > 0) { clstate->message_count++; // added clstate->byte_count+=rec_count; handle_command(buf,clstate); // added } /* if we got nothing, that means the connection is closed */ else { printf("closing connection...\n"); if(clstate->prev == 0) { clients = clstate->next; if(clients) clients->prev = 0; } else { clstate->prev->next = clstate->next; if(clstate->next) clstate->next->prev = clstate->prev; } client_count--; // tell the others char send_msg[255]; sprintf(send_msg, "%s disconnected.\n", clstate->name); broadcast_msg(send_msg, clstate); printf("%s disconnected. A total of %d bytes received from %s.\n",clstate->name, clstate->byte_count, clstate->name); // clean up the rest of the state shutdown(clstate->socket,SHUT_RDWR); close(clstate->socket); FD_CLR(clstate->socket,&readset); struct client_state *tofree = clstate; clstate = clstate->next; free(tofree); continue; } } // end if(FD_ISSET... clstate=clstate->next; } // end while } shutdown(server_sock,SHUT_RDWR); }
void listen_from_peers() { struct peer_state* peer = peers; unsigned int msglen = 0; while(missing_blocks() > 0) { fd_set fdrset_clone; fd_set fdwset_clone; FD_COPY(&fdrset,&fdrset_clone); FD_COPY(&fdwset,&fdwset_clone); int rdy = select(FD_SETSIZE,&fdrset_clone,&fdwset_clone,0, 0); if(rdy <= 0) { continue; } peer = peers; if(active_peers() == 0){ break; } while(peer){ if(FD_ISSET(peer->socket,&fdwset_clone)){ if(peer->connected == 0){ //to send the handshake if it is not connected send_handshake(peer); } else if(peer->send_count > 0) { //to send the have/interested/piece messages to peers send_buffed_msg(peer); } } if(FD_ISSET(peer->socket,&fdrset_clone)) { int newbytes = recv(peer->socket,peer->incoming+peer->count,BUFSIZE-peer->count,0); if(newbytes <= 0){ peer->trying_to_connect = 0; if(newbytes == 0){ piece_status[peer->requested_piece] = PIECE_EMPTY; } disconnet_peer(peer); reconnect_peer(peer); peer = peer->next; continue; } peer->count += newbytes; if(!peer->handshaked){ peer->count -= peer->incoming[0]+49; if(peer->count) { memmove(peer->incoming,peer->incoming + peer->incoming[0]+49,peer->count); } peer->handshaked = 1; } if(memcmp(peer->incoming+peer->incoming[0]+8+20,"-UICCS450-",strlen("-UICCS450-"))==0) { fprintf(stderr,"Caught a CS450 peer, exiting.\n"); disconnet_peer(peer); continue; } while(peer->count >= (ntohl(((int*)peer->incoming)[0])) + 4){ msglen = ntohl(((int*)peer->incoming)[0]); switch(peer->incoming[4]) { // CHOKE case 0: { if(debug) fprintf(stderr,"Choke\n"); peer->choked = 1; piece_status[peer->requested_piece]=PIECE_EMPTY; peer->requested_piece = -1; break; } // UNCHOKE case 1: { if(debug) fprintf(stderr,"Unchoke\n"); peer->choked = 0; peer->requested_piece = next_piece(-1,peer); request_block(peer,peer->requested_piece,0); break; } //Interested case 2: { //dev_notifier(); send_choke_unchoke_msg(peer,0); //ischoked = 0 peer->not_interested = 0; break; } //Not interested case 3: { //dev_notifier(); peer->not_interested = 1; break; } // HAVE -- update the bitfield for this peer case 4: { int piece = ntohl(*((int*)&peer->incoming[5])); int bitfield_byte = piece/8; int bitfield_bit = piece%8; if(debug) fprintf(stderr,"Have %d\n",piece); peer->bitfield[bitfield_byte] |= 1 << (7 - bitfield_bit); piece_occurence_value[piece]++; send_interested(peer); break; } // BITFIELD -- set the bitfield for this peer case 5: //peer->choked = 0; //commenting it according to prof's note in class if(debug) printf("Bitfield of length %d\n",msglen-1); int fieldlen = msglen - 1; if(fieldlen != (file_length/piece_length/8+1)) { disconnet_peer(peer); if(active_peers() == 0){ break; } peer = peer->next; continue; } memcpy(peer->bitfield,peer->incoming+5,fieldlen); read_bit_maps(peer->bitfield,fieldlen); send_interested(peer); break; //Request piece case 6: { if(peer->i_choked_it == 1) break; decode_request_send_piece_to_peer(peer); } break; // PIECE case 7: { //make the tit for tatter peer->send_recv_balancer++; if(peer->i_choked_it && peer->send_recv_balancer == 0){ peer->i_choked_it = 0; send_choke_unchoke_msg(peer,0); //unchoke peer } int piece = ntohl(*((int*)&peer->incoming[5])); int offset = ntohl(*((int*)&peer->incoming[9])); int datalen = msglen - 9; fprintf(stderr,"Writing piece %d, offset %d, ending at %d\n",piece,offset,piece*piece_length+offset+datalen); write_block(peer->incoming+13,piece,offset,datalen,1); draw_state(); offset+=datalen; if(offset==piece_length || (piece*piece_length+offset == file_length) ) { broadcast_have_msg(piece); draw_state(); if(debug) fprintf(stderr,"Reached end of piece %d at offset %d\n",piece,offset); peer->requested_piece=next_piece(piece,peer); offset = 0; } request_block(peer,peer->requested_piece,offset); break; } } drop_message(peer); } } peer = peer->next; } } return; }
bool select_call::wait(const timeval &elapsed) { timeval timeout, *pto = NULL; timespec to_pselect, *pto_pselect = NULL; BULLSEYE_EXCLUDE_BLOCK_START if (m_n_all_ready_fds > 0) { __log_panic("wait() called when there are ready fd's!!!"); // YossiE TODO make this and some more checks as debug assertions // In all functions } BULLSEYE_EXCLUDE_BLOCK_END // Restore original sets if (m_b_run_prepare_to_poll) { if (m_readfds) FD_COPY(m_readfds, &m_os_rfds, m_nfds); if (m_writefds) FD_COPY(m_writefds, &m_os_wfds, m_nfds); if (m_exceptfds)FD_COPY(m_exceptfds, &m_orig_exceptfds, m_nfds); } // Call OS select() on original sets + CQ epfd in read set if (m_readfds) FD_SET(m_cqepfd, m_readfds); if (m_timeout) { tv_sub(m_timeout, &elapsed, &timeout); if (timeout.tv_sec < 0 || timeout.tv_usec < 0) { // Already reached timeout return false; } pto = &timeout; } __log_func("going to wait on select CQ+OS nfds=%d cqfd=%d pto=%p!!!", m_nfds_with_cq, m_cqepfd, pto); // ACTUAL CALL TO SELECT if (m_sigmask) { if (pto) { to_pselect.tv_sec = pto->tv_sec; to_pselect.tv_nsec = pto->tv_usec * 1000; pto_pselect = &to_pselect; } m_n_all_ready_fds = orig_os_api.pselect(m_nfds, m_readfds, m_writefds, m_exceptfds, pto_pselect, m_sigmask); } else { m_n_all_ready_fds = orig_os_api.select(m_nfds_with_cq, m_readfds, m_writefds, m_exceptfds, pto); } __log_func("done select CQ+OS nfds=%d cqfd=%d pto=%p ready=%d!!!", m_nfds_with_cq, m_cqepfd, pto, m_n_all_ready_fds); if (m_n_all_ready_fds < 0) { vma_throw_object(io_mux_call::io_error); } // Clear CQ from the set and don't count it if (m_readfds) { if (FD_ISSET(m_cqepfd, m_readfds)) { FD_CLR(m_cqepfd, m_readfds); // Not needed if m_readfds is NULL --m_n_all_ready_fds; return true; } } return false; }
int main(int argc, char **argv) { int i, c, maxfd, rval, qpsock, fd; fd_set fds, rfds; FILE *fp, *client[MAX_CLIENT]; m_debug = 0; l_debug = LOG_INFO; fp = NULL; for (i = 0; i < MAX_CLIENT; i++) client[i] = NULL; while ((c = getopt(argc, argv, "f:vdl:")) != -1) { switch (c) { case 'f': altqconfigfile = optarg; break; case 'v': l_debug = LOG_DEBUG; m_debug |= DEBUG_ALTQ; daemonize = 0; break; case 'd': daemonize = 0; break; case 'l': l_debug = atoi(optarg); break; default: usage(); } } signal(SIGINT, sig_handler); signal(SIGTERM, sig_handler); signal(SIGHUP, sig_handler); signal(SIGPIPE, sig_handler); if (daemonize) openlog("altqd", LOG_PID, LOG_DAEMON); if (qcmd_init() != 0) { if (daemonize) closelog(); exit(1); } /* * open a unix domain socket for altqd clients */ if ((qpsock = socket(AF_LOCAL, SOCK_STREAM, 0)) < 0) LOG(LOG_ERR, errno, "can't open unix domain socket"); else { struct sockaddr_un addr; bzero(&addr, sizeof(addr)); addr.sun_family = AF_LOCAL; strlcpy(addr.sun_path, QUIP_PATH, sizeof(addr.sun_path)); unlink(QUIP_PATH); if (bind(qpsock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { LOG(LOG_ERR, errno, "can't bind to %s", QUIP_PATH); close(qpsock); qpsock = -1; } chmod(QUIP_PATH, 0666); if (listen(qpsock, SOMAXCONN) < 0) { LOG(LOG_ERR, errno, "can't listen to %s", QUIP_PATH); close(qpsock); qpsock = -1; } } if (daemonize) { daemon(0, 0); /* save pid to the pid file (/var/tmp/altqd.pid) */ #ifdef __FreeBSD__ { FILE *fp; if ((fp = fopen(ALTQD_PID_FILE, "w")) != NULL) { fprintf(fp, "%d\n", getpid()); fclose(fp); } else LOG(LOG_WARNING, errno, "can't open pid file"); } #else pidfile(NULL); #endif } else { /* interactive mode */ fp = stdin; printf("\nEnter ? or command:\n"); printf("altqd %s> ", cur_ifname()); fflush(stdout); } /* * go into the command mode. */ FD_ZERO(&fds); maxfd = 0; if (fp != NULL) { fd = fileno(fp); if (fd == -1) LOG(LOG_ERR, 0, "bad file descriptor", QUIP_PATH); } else fd = -1; if (fd != -1) { FD_SET(fd, &fds); maxfd = MAX(maxfd, fd + 1); } if (qpsock >= 0) { FD_SET(qpsock, &fds); maxfd = MAX(maxfd, qpsock + 1); } rval = 1; while (rval) { if (gotsig_hup) { qcmd_destroyall(); gotsig_hup = 0; LOG(LOG_INFO, 0, "reinitializing altqd..."); if (qcmd_init() != 0) { LOG(LOG_INFO, 0, "reinitialization failed"); break; } } if (gotsig_term || gotsig_int) { LOG(LOG_INFO, 0, "Exiting on signal %d", gotsig_term ? SIGTERM : SIGINT); break; } FD_COPY(&fds, &rfds); if (select(maxfd, &rfds, NULL, NULL, NULL) < 0) { if (errno != EINTR) err(1, "select"); continue; } /* * if there is command input, read the input line, * parse it, and execute. */ if (fp && FD_ISSET(fd, &rfds)) { rval = do_command(fp); if (rval == 0) { /* quit command or eof on input */ LOG(LOG_INFO, 0, "Exiting."); } else if (fp == stdin) printf("altqd %s> ", cur_ifname()); fflush(stdout); } else if (qpsock >= 0 && FD_ISSET(qpsock, &rfds)) { /* * quip connection request from client via unix * domain socket; get a new socket for this * connection and add it to the select list. */ int newsock = accept(qpsock, NULL, NULL); if (newsock == -1) { LOG(LOG_ERR, errno, "accept"); continue; } FD_SET(newsock, &fds); for (i = 0; i < MAX_CLIENT; i++) if (client[i] == NULL) { client[i] = fdopen(newsock, "r+"); break; } maxfd = MAX(maxfd, newsock + 1); } else { /* * check input from a client via unix domain socket */ for (i = 0; i < MAX_CLIENT; i++) { int fd1; if (client[i] == NULL) continue; fd1 = fileno(client[i]); if (FD_ISSET(fd1, &rfds)) { if (quip_input(client[i]) != 0 || fflush(client[i]) != 0) { /* connection closed */ fclose(client[i]); client[i] = NULL; FD_CLR(fd1, &fds); } } } } } /* cleanup and exit */ qcmd_destroyall(); if (qpsock >= 0) (void)close(qpsock); unlink(QUIP_PATH); for (i = 0; i < MAX_CLIENT; i++) if (client[i] != NULL) (void)fclose(client[i]); if (daemonize) { #ifdef __FreeBSD__ /* if we have a pid file, remove it */ unlink(ALTQD_PID_FILE); #endif closelog(); } exit(0); }
int main(int argc, char **argv) { int ch_options, errs, f, funix, *finet, i, lfd, socket_debug; fd_set defreadfds; struct sockaddr_un un, fromunix; struct sockaddr_storage frominet; socklen_t fromlen; sigset_t omask, nmask; struct servent *sp, serv; int inet_flag = 0, inet6_flag = 0; euid = geteuid(); /* these shouldn't be different */ uid = getuid(); ch_options = 0; socket_debug = 0; gethostname(local_host, sizeof(local_host)); progname = "lpd"; if (euid != 0) errx(EX_NOPERM,"must run as root"); errs = 0; while ((i = getopt(argc, argv, "cdlpswW46")) != -1) switch (i) { case 'c': /* log all kinds of connection-errors to syslog */ ch_options |= LPD_LOGCONNERR; break; case 'd': socket_debug++; break; case 'l': lflag++; break; case 'p': /* letter initially used for -s */ /* * This will probably be removed with 5.0-release. */ /* FALLTHROUGH */ case 's': /* secure (no inet) */ sflag++; break; case 'w': /* netbsd uses -w for maxwait */ /* * This will be removed after the release of 4.4, as * it conflicts with -w in netbsd's lpd. For now it * is just a warning, so we won't suddenly break lpd * for anyone who is currently using the option. */ syslog(LOG_WARNING, "NOTE: the -w option has been renamed -W"); syslog(LOG_WARNING, "NOTE: please change your lpd config to use -W"); /* FALLTHROUGH */ case 'W': /* allow connections coming from a non-reserved port */ /* (done by some lpr-implementations for MS-Windows) */ ch_options |= LPD_NOPORTCHK; break; case '4': family = PF_INET; inet_flag++; break; case '6': #ifdef INET6 family = PF_INET6; inet6_flag++; #else errx(EX_USAGE, "lpd compiled sans INET6 (IPv6 support)"); #endif break; /* * The following options are not in FreeBSD (yet?), but are * listed here to "reserve" them, because the option-letters * are used by either NetBSD or OpenBSD (as of July 2001). */ case 'b': /* set bind-addr */ case 'n': /* set max num of children */ case 'r': /* allow 'of' for remote ptrs */ /* ...[not needed in freebsd] */ /* FALLTHROUGH */ default: errs++; } if (inet_flag && inet6_flag) family = PF_UNSPEC; argc -= optind; argv += optind; if (errs) usage(); if (argc == 1) { if ((i = atoi(argv[0])) == 0) usage(); if (i < 0 || i > USHRT_MAX) errx(EX_USAGE, "port # %d is invalid", i); serv.s_port = htons(i); sp = &serv; argc--; } else { sp = getservbyname("printer", "tcp"); if (sp == NULL) errx(EX_OSFILE, "printer/tcp: unknown service"); } if (argc != 0) usage(); /* * We run chkprintcap right away to catch any errors and blat them * to stderr while we still have it open, rather than sending them * to syslog and leaving the user wondering why lpd started and * then stopped. There should probably be a command-line flag to * ignore errors from chkprintcap. */ { pid_t pid; int status; pid = fork(); if (pid < 0) { err(EX_OSERR, "cannot fork"); } else if (pid == 0) { /* child */ execl(_PATH_CHKPRINTCAP, _PATH_CHKPRINTCAP, (char *)0); err(EX_OSERR, "cannot execute %s", _PATH_CHKPRINTCAP); } if (waitpid(pid, &status, 0) < 0) { err(EX_OSERR, "cannot wait"); } if (WIFEXITED(status) && WEXITSTATUS(status) != 0) errx(EX_OSFILE, "%d errors in printcap file, exiting", WEXITSTATUS(status)); } #ifndef DEBUG /* * Set up standard environment by detaching from the parent. */ daemon(0, 0); #endif openlog("lpd", LOG_PID, LOG_LPR); syslog(LOG_INFO, "lpd startup: logging=%d%s%s", lflag, socket_debug ? " dbg" : "", sflag ? " net-secure" : ""); (void) umask(0); /* * NB: This depends on O_NONBLOCK semantics doing the right thing; * i.e., applying only to the O_EXLOCK and not to the rest of the * open/creation. As of 1997-12-02, this is the case for commonly- * used filesystems. There are other places in this code which * make the same assumption. */ lfd = open(_PATH_MASTERLOCK, O_WRONLY|O_CREAT|O_EXLOCK|O_NONBLOCK, LOCK_FILE_MODE); if (lfd < 0) { if (errno == EWOULDBLOCK) /* active daemon present */ exit(0); syslog(LOG_ERR, "%s: %m", _PATH_MASTERLOCK); exit(1); } fcntl(lfd, F_SETFL, 0); /* turn off non-blocking mode */ ftruncate(lfd, 0); /* * write process id for others to know */ sprintf(line, "%u\n", getpid()); f = strlen(line); if (write(lfd, line, f) != f) { syslog(LOG_ERR, "%s: %m", _PATH_MASTERLOCK); exit(1); } signal(SIGCHLD, reapchild); /* * Restart all the printers. */ startup(); (void) unlink(_PATH_SOCKETNAME); funix = socket(AF_UNIX, SOCK_STREAM, 0); if (funix < 0) { syslog(LOG_ERR, "socket: %m"); exit(1); } sigemptyset(&nmask); sigaddset(&nmask, SIGHUP); sigaddset(&nmask, SIGINT); sigaddset(&nmask, SIGQUIT); sigaddset(&nmask, SIGTERM); sigprocmask(SIG_BLOCK, &nmask, &omask); (void) umask(07); signal(SIGHUP, mcleanup); signal(SIGINT, mcleanup); signal(SIGQUIT, mcleanup); signal(SIGTERM, mcleanup); memset(&un, 0, sizeof(un)); un.sun_family = AF_UNIX; strcpy(un.sun_path, _PATH_SOCKETNAME); #ifndef SUN_LEN #define SUN_LEN(unp) (strlen((unp)->sun_path) + 2) #endif if (bind(funix, (struct sockaddr *)&un, SUN_LEN(&un)) < 0) { syslog(LOG_ERR, "ubind: %m"); exit(1); } (void) umask(0); sigprocmask(SIG_SETMASK, &omask, (sigset_t *)0); FD_ZERO(&defreadfds); FD_SET(funix, &defreadfds); listen(funix, 5); if (sflag == 0) { finet = socksetup(family, socket_debug); } else finet = NULL; /* pretend we couldn't open TCP socket. */ if (finet) { for (i = 1; i <= *finet; i++) { FD_SET(finet[i], &defreadfds); listen(finet[i], 5); } } /* * Main loop: accept, do a request, continue. */ memset(&frominet, 0, sizeof(frominet)); memset(&fromunix, 0, sizeof(fromunix)); if (lflag) syslog(LOG_INFO, "lpd startup: ready to accept requests"); /* * XXX - should be redone for multi-protocol */ for (;;) { int domain, nfds, s; fd_set readfds; FD_COPY(&defreadfds, &readfds); nfds = select(20, &readfds, 0, 0, 0); if (nfds <= 0) { if (nfds < 0 && errno != EINTR) syslog(LOG_WARNING, "select: %m"); continue; } domain = -1; /* avoid compile-time warning */ s = -1; /* avoid compile-time warning */ if (FD_ISSET(funix, &readfds)) { domain = AF_UNIX, fromlen = sizeof(fromunix); s = accept(funix, (struct sockaddr *)&fromunix, &fromlen); } else { for (i = 1; i <= *finet; i++) if (FD_ISSET(finet[i], &readfds)) { domain = AF_INET; fromlen = sizeof(frominet); s = accept(finet[i], (struct sockaddr *)&frominet, &fromlen); } } if (s < 0) { if (errno != EINTR) syslog(LOG_WARNING, "accept: %m"); continue; } if (fork() == 0) { /* * Note that printjob() also plays around with * signal-handling routines, and may need to be * changed when making changes to signal-handling. */ signal(SIGCHLD, SIG_DFL); signal(SIGHUP, SIG_IGN); signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); signal(SIGTERM, SIG_IGN); (void) close(funix); if (sflag == 0 && finet) { for (i = 1; i <= *finet; i++) (void)close(finet[i]); } dup2(s, STDOUT_FILENO); (void) close(s); if (domain == AF_INET) { /* for both AF_INET and AF_INET6 */ from_remote = 1; chkhost((struct sockaddr *)&frominet, ch_options); } else from_remote = 0; doit(); exit(0); } (void) close(s); } }
void *netServerThread(void *eData) { x_try netServer *sData = (netServer*)eData; fd_set selectSet; fd_set copySet; mpMutex *mtx = sData->r_mutex; mpMutexLock(mtx); FD_ZERO(&selectSet); FD_SET(sData->m_socket, &selectSet); mpMutexUnlock(mtx); for (;;) { FD_COPY(&selectSet, ©Set); //Wait for a bit of time, locking the mutex... mpMutexLock(mtx); if (sData->m_client == NULL) { if (sData->m_socket != -1) { struct timeval to; to.tv_sec = 5; to.tv_usec = 0; int sel = select(sData->m_socket+1, ©Set, NULL, NULL, &to); if (sel == -1) { mpMutexUnlock(mtx); goto done; } if (!((sData->m_flags) & NETS_SINGLE_CLIENT) || sData->m_runningThreads == 0) { if (sel != 0) //Not timed out { struct sockaddr remoteAddress; socklen_t remoteSize; remoteSize = sizeof(remoteAddress); int clientSock = accept(sData->m_socket, &remoteAddress, &remoteSize); if (clientSock != -1) { printf("Server got connection\n"); netClient *client = netClientFromSocket(clientSock); if (client != NULL) { pthread_t tmp; sData->m_client = client; sData->m_runningThreads++; x_pthread_create(&tmp, NULL, netServerConnection, eData); } } } } } else { mpMutexUnlock(mtx); goto done; } } mpMutexUnlock(mtx); } x_catch(e) printf("%s",errorMsg(e)); x_finally done: printf("Killed Server!\n"); return NULL; }
int main( int argc, char** argv ) { int i, j, ret; char buf[1024]; size_t buf_len; // Parse args. if ( argc != 2 ) { (void) fprintf( stderr, "usage: %s port#\n", argv[0] ); exit( 1 ); } // Initialize server init_server( (unsigned short) atoi( argv[1] ) ); // Get file descripter table size and initize request table maxfd = getdtablesize(); requestP = ( request* ) malloc( sizeof( request ) * maxfd ); if ( requestP == (request*) 0 ) ERR_EXIT( "out of memory allocating all requests" ); for ( i = 0; i < maxfd; i ++ ) init_request( &requestP[i] ); requestP[ svr.listen_fd ].conn_fd = svr.listen_fd; requestP[ svr.listen_fd ].status = READING; strcpy( requestP[ svr.listen_fd ].host, svr.hostname ); // Loop for handling connections fprintf( stderr, "\nstarting on %.80s, port %d, fd %d, maxconn %d...\n", svr.hostname, svr.port, svr.listen_fd, maxfd ); // mark socket that is no-blocking fcntl( svr.listen_fd, F_SETFL, O_NONBLOCK ); // work flags struct fd_set theConnectedFDs; // set of connected fds FD_ZERO( &theConnectedFDs ); // clear the set struct fd_set theCommandFDs; while (1) { int conn_fd; struct sockaddr_in cliaddr; socklen_t clilen = sizeof(cliaddr); // Fetch Check Connection if( (conn_fd = accept( svr.listen_fd, (struct sockaddr *) &cliaddr, &clilen ))!=-1){ // OK requestP[conn_fd].conn_fd = conn_fd; requestP[conn_fd].status = READING; strcpy( requestP[conn_fd].host, inet_ntoa( cliaddr.sin_addr ) ); fprintf( stderr, "getting a new connection... fd %d from %s\n", conn_fd, requestP[conn_fd].host ); FD_SET( conn_fd, &theConnectedFDs ); } FD_COPY(&theConnectedFDs, &theCommandFDs); // update theCommandFDs struct timeval req_timeout = { 0, 10000 }; // Scan The Descriptors for Read Commands int available_fds = select( maxfd, &theCommandFDs, NULL, NULL, &req_timeout ); if( available_fds > 0 ){ for( i=3; i<maxfd; i++ ){ if( FD_ISSET(i, &theCommandFDs) ){ conn_fd = i; // Read Buffer buf_len = requestP[conn_fd].buf_len; ret = handle_read( &requestP[conn_fd] ); // Check Connection if( requestP[conn_fd].buf_len == buf_len ){ fprintf(stderr, "disconnection detected: fd %d.\n", conn_fd ); fprintf(stderr, "someone logout\n"); close( requestP[conn_fd].conn_fd ); free_request( &requestP[conn_fd] ); FD_CLR( conn_fd, &theConnectedFDs ); }else if( ret==0 ){ // Process Command const char* command_content = requestP[conn_fd].buf; fprintf( stderr, "receive complete command from fd %d\n", conn_fd ); if( strncmp( command_content, "<RD>", 4 )==0 ){ requestP[conn_fd].status = WRITING; }else if( strncmp( command_content, "<WR>", 4 )==0 ){ strcpy( buf, command_content ); buf_len = requestP[conn_fd].buf_len; // Write out for ( j=3; j<maxfd; j++ ){ if ( requestP[j].status == WRITING ){ // Write! write( requestP[j].conn_fd, buf, buf_len ); } } // Clean! close( requestP[conn_fd].conn_fd ); free_request( &requestP[conn_fd] ); FD_CLR( conn_fd, &theConnectedFDs ); } fputs( "command processing completed.\n", stderr ); } } } } sched_yield(); } // free( requestP ); return 0; }