/* * UICI Server * Open a UICI port specified as a command-line argument * and wait for requests. When a request arrives, * fork a child to handle the communication and resume * waiting for another request. */ int main(int argc, char *argv[]) { u_port_t portnumber; int listenfd; int communfd; char client[MAX_CANON]; int bytes_copied; pid_t child; if (argc != 2) { fprintf(stderr, "Usage: %s port\n", argv[0]); return 1; } portnumber = (u_port_t) atoi(argv[1]); if ((listenfd = u_open(portnumber)) < 0) { perror("Listen endpoint creation failed"); return 1; } fprintf(stderr, "[%ld]: Waiting for the first connection on port %d\n", (long)getpid(), (int)portnumber); for ( ; ; ) { if ((communfd = u_accept(listenfd, client, MAX_CANON)) != -1) { fprintf(stderr, "[%ld]: A connection has been received from %s\n", (long) getpid(), client); if ((child = fork()) == -1) perror("Could not fork a child"); if (child == 0) { /* child code */ r_close(listenfd); bytes_copied = copy2files(communfd, STDOUT_FILENO, STDIN_FILENO, communfd); r_close(communfd); fprintf(stderr, "[%ld]:Bytes transferred = %d\n", (long) getpid(), bytes_copied); return 0; } else { /* parent code */ r_close(communfd); while (r_waitpid(-1, NULL, WNOHANG) > 0) ; /* clean up zombies */ } } else perror("Accept failed"); } }
void * SelecionaDescritores(void *args) { // Indica se o socket com o nó principal esta ativo. bool flagSockConectado = false; // Sockets a serem manipulados. int sockfd = -1; int accfd = -1; int listenfd = -1; // Porta e ip do servidor principal. int portaConnect; char servidor[TAM_STR_IP + 1]; // Ponteiro p/ argumentos. TpArgumento * argumentos; char maquina[MAX_CANON]; //Variaveis necessarias para o uso de "select". //int i; //int maxi; int nready; int peerfd; //Armazena temporariamente o descritor que estah sendo checado. // Inicializa variaveis. argumentos = (TpArgumento *)args; listenfd = argumentos->listenfd; portaConnect = argumentos->portaConnect; // Se for -1 eh pq eh um noh principal strcpy(servidor, argumentos->ipConnect); // Se for NULL eh pq eh um noh principal maxfd = listenfd; // Valor inteiro do maior descritor utilizado. Inicialmente soh temos o listenfd //maxi = -1; FD_ZERO(&allset); // Zera todos os bits do set de descritores que serao checados FD_SET(listenfd, &allset); // Seta o bit do listenfd, ou seja, coloca listenfd no set de descritores q sera usado por "select" FD_SET(fileno(stdin), &allset); if(fileno(stdin) > maxfd) maxfd = fileno(stdin); if(!DadosAplicacao.principal) { puts("Entrou como naum principal"); while((sockfd = u_connect(portaConnect, servidor)) == -1) { sleep(1); puts("Tentando conectar no peer principal..."); } DadosAplicacao.sockPrincipalConectado = sockfd; if(sockfd >= 0) { FD_SET(sockfd, &allset); // Utiliza-se esse socket para falar com o noh principal if(sockfd > maxfd) maxfd = sockfd; insereTabelaSocket(sockfd); flagSockConectado = true; } } // 'zSeta' os TIMER's. SetTimer( DadosAplicacao.intervaloHello, TIMER_HELLO, 0 ); for(;;) { #ifdef DEBUG fprintf(stdout, "\nInicio do FOR\n"); fprintf(stdout, "SockPrincipal: %d\n\n\n", DadosAplicacao.sockPrincipalConectado); #endif if(DadosAplicacao.principal && (DadosAplicacao.sockPrincipalConectado != -1) && (!flagSockConectado)) { sockfd = DadosAplicacao.sockPrincipalConectado; if(sockfd >= 0) { FD_SET(sockfd, &allset); // Utiliza-se esse socket para falar com o noh principal if(sockfd > maxfd) maxfd = sockfd; insereTabelaSocket(sockfd); flagSockConectado = true; } } // Seta o conjunto de descritores que serah checado para eventos do tipo "read" rset = allset; #ifdef DEBUG if(RetornaTimer() == NULL) fprintf(stdout, "Timer NULL\n"); else imprimeTimer(); #endif //printf("\nANTES DO SELECT:\n"); //printf("nready: %d\terrno: %d(%d)\n\n", nready, errno, EINTR); // Retorna o numero de sockets prontos ou zero caso seja um evento de timeout. while(((nready = select(maxfd + 1, &rset, NULL, NULL, RetornaTimer()) ) == -1) && (errno == EINTR)); //printf("\n-----> SELECT <-----\n"); // Caso select retorne -1 e o tipo de erro naum seja interrupcao if( nready == -1 ) { printf("\n-----> ERRO SELECT <-----\n"); puts(strerror(errno)); exit(1); } //********************************* // TRATA EVENTO DE TIMEOUT //********************************* if(nready == 0) { // printf("\n-----> TIMER <-----\n"); #ifdef DEBUG puts("Vou chamar o trataTimer"); #endif trataTimer(); } //********************************* // TRATA PEDIDOS DE CONEXOES //********************************* if(FD_ISSET(listenfd, &rset)) { printf("\n-----> CONEXAO <-----\n"); //fprintf(stdout, "*** Listen ***\n"); if((accfd = u_accept(listenfd, maquina)) >= 0) { puts("Conectou"); insereTabelaSocket(accfd); } else{ // TODO Accept deu erro - TRATAR } FD_SET(accfd, &allset); // Seta o bit para o novo descritor no set de descritores q estao sendo tratados por "select" if(accfd > maxfd) maxfd = accfd; // Variavel q sera utilizada na chamada a "select" if(--nready <= 0) // Caso o unico descritor setado for o listenfd continue; // Nao ha mais descritores pendentes de serem tratados } //********************************** // TRATA EVENTOS DE TECLADO //********************************** if( FD_ISSET( fileno(stdin), &rset ) ) { printf("\n-----> TECLADO <-----\n"); fprintf(stdout, "*** Teclado ***\n"); readCmdLine(); } //*********************************** // TRATA RECEBIMENTO DE MENSAGENS //*********************************** if((peerfd = encontraTabelaSocketPorRSet(rset)) != -1) { //#ifdef DEBUG // printf("\n-----> MENSAGEM <-----\n"); // printf("Socket: %d\n", peerfd); //#endif trataRecebimento(peerfd); if (--nready <= 0 ) continue; } } }