int ssl_stream::recv( void* buffer, int size, long timeout_sec ) { if( buffer == NULL || size < 0 ) { return 0; } int offset = 0; while( size > 0 ) { int res = SSL_read( ssl_, buffer, size ); int ssl_err = SSL_get_error( ssl_, res ); if( ssl_err == SSL_ERROR_NONE ) { size -= res; offset += res; if( !SSL_pending( ssl_ ) ) { break; } } else if( ssl_err == SSL_ERROR_ZERO_RETURN ) { break; } else if( ssl_err == SSL_ERROR_WANT_READ ) { if( check_select( socket_, true, false, timeout_sec ) == false ) { break; } } else if( ssl_err == SSL_ERROR_WANT_WRITE ) { /* We get a WANT_WRITE if we're trying to rehandshake and we block on a write during that rehandshake. We need to wait on the socket to be writeable but reinitiate the read when it is */ if( check_select( socket_, true, true, timeout_sec ) == false ) { break; } } else { break; } } return offset; }
bool ssl_stream::open( SOCKET socket, long timeout_sec ) { socket_ = socket; SSL_library_init(); SSL_load_error_strings(); ssl_ctx_ = SSL_CTX_new( SSLv23_client_method() ); if( ssl_ctx_ == NULL ) { return false; } ssl_ = SSL_new( ssl_ctx_ ); if( ssl_ == NULL ) { return false; } SSL_set_fd( ssl_, static_cast< int >( socket_ ) ); SSL_set_mode( ssl_, SSL_MODE_AUTO_RETRY ); while( 1 ) { int res = SSL_connect( ssl_ ); switch( SSL_get_error( ssl_, res ) ) { case SSL_ERROR_NONE: return true; break; case SSL_ERROR_WANT_WRITE: if( check_select( socket_, /*check_read = */ false, /*check_write = */ true, timeout_sec ) == false ) { return false; } break; case SSL_ERROR_WANT_READ: if( check_select( socket_, /*check_read = */ true, /*check_write = */ false, timeout_sec ) == false ) { return false; } break; default: return false; } } return true; }
bool ssl_stream::send_sync( const void* buffer, int size, long timeout_sec ) { if( buffer == NULL || size < 0 ) { return false; } int sent_pos = 0; const char* temp_buffer = reinterpret_cast< const char* >( buffer ); while( size > 0 ) { /* Try to write */ int res = SSL_write( ssl_, temp_buffer + sent_pos, size ); switch( SSL_get_error( ssl_, res ) ) { /* We wrote something*/ case SSL_ERROR_NONE: size -= res; sent_pos += res; break; /* We would have blocked */ case SSL_ERROR_WANT_WRITE: if( check_select( socket_, false, true, timeout_sec ) == false ) { return false; } break; /* We get a WANT_READ if we're trying to rehandshake and we block on write during the current connection. We need to wait on the socket to be readable but reinitiate our write when it is */ case SSL_ERROR_WANT_READ: if( check_select( socket_, true, true, timeout_sec ) == false ) { return false; } break; /* Some other error */ default: return false; } } return true; }
bool normal_stream::send_sync( const void* buffer, int size, long timeout_sec ) { if( buffer == NULL || size < 0 ) { return false; } int sent_pos = 0; const char* temp_buffer = reinterpret_cast< const char* >( buffer ); while( size > 0 ) { if( check_select( socket_, false, true, timeout_sec ) == false ) { return false; } int res = ::send( socket_, temp_buffer + sent_pos, size, 0 ); if( res == SOCKET_ERROR || res == 0 ) { return false; } size -= res; sent_pos += res; } return true; }
int main(int argc, char **argv) { struct termios oldline; t_area ar; if (argc > 1) { non_canonical_mode(&oldline); init_term(&ar, argv, argc); display_arguments(&ar); while ((ar.len = read(0, ar.buff, sizeof(ar.buff)))) { x_read(ar.len); init_lines(&ar, &oldline); check_ctrl(&ar); check_keys(&ar, ar.len); check_select(&ar); if (my_exit(&oldline, &ar) == 1 || void_exit(&ar, &oldline) == 1) return (EXIT_SUCCESS); } restore_mode(&oldline, &ar); free_struct(&ar); } else my_put_error(ERR_ARGV); return (EXIT_SUCCESS); }
/* * Verify that closing a connecting socket before it is accepted will result in * no activity on the accepting side later. */ void test_connect_close(const struct socket_test_info *info) { int server_sd, client_sd, sd, on; struct sockaddr_storage addr; socklen_t len; debug("entering test_connect_close()"); SOCKET(server_sd, info->domain, info->type, 0); on = 1; (void)setsockopt(server_sd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); if (bind(server_sd, info->serveraddr, info->serveraddrlen) == -1) test_fail("bind() should have worked"); if (info->callback_set_listen_opt != NULL) info->callback_set_listen_opt(server_sd); if (listen(server_sd, 8) == -1) test_fail("listen() should have worked"); fcntl(server_sd, F_SETFL, fcntl(server_sd, F_GETFL) | O_NONBLOCK); check_select(server_sd, 0 /*read*/, 1 /*write*/, 0 /*block*/); SOCKET(client_sd, info->domain, info->type, 0); fcntl(client_sd, F_SETFL, fcntl(client_sd, F_GETFL) | O_NONBLOCK); if (connect(client_sd, info->clientaddr, info->clientaddrlen) != -1 || errno != EINPROGRESS) test_fail("connect() should have yielded EINPROGRESS"); check_select_cond(client_sd, 0 /*read*/, 0 /*write*/, 0 /*block*/, !info->ignore_select_delay); check_select_cond(server_sd, 1 /*read*/, 1 /*write*/, 0 /*block*/, !info->ignore_select_delay); close(client_sd); check_select_cond(server_sd, 0 /*read*/, 1 /*write*/, 0 /*block*/, !info->ignore_select_delay); len = sizeof(addr); errno = 0; if ((sd = accept(server_sd, (struct sockaddr *) &addr, &len)) != -1) { if (!info->ignore_accept_delay) { test_fail("accept() should have failed"); } close(sd); } else if (errno != EAGAIN) { test_fail("accept() should have yielded EAGAIN"); } close(server_sd); info->callback_cleanup(); debug("leaving test_connect_close()"); }
static void tune_in(void) { int selfd; //logmsg("[%s: tune_in(...)] *** ENTER ***", __FILE__); init_signals(); //logmsg("[%s: tune_in(...)] Signals initialized", __FILE__); //lock_ourselves(); init_regexps(); //logmsg("[%s: tune_in(...)] Regexps initialized", __FILE__); // BEGIN HERE if (fifo_exists(ZTEBLADEFM_PIPE_CMD)) { int rv = mkfifo(ZTEBLADEFM_PIPE_CMD, 0666); if (rv < 0) { // handle condition here.. panic("[%s:tune_in(...) @ %d] - Could not mkfifo %s.", __FILE__, __LINE__, ZTEBLADEFM_PIPE_CMD); } } if (fifo_exists(ZTEBLADEFM_PIPE_STATUS)) { int rv = mkfifo(ZTEBLADEFM_PIPE_STATUS, 0666); if (rv < 0) { // handle condition here.. panic("[%s:tune_in(...) @ %d] - Could not mkfifo %s.", __FILE__, __LINE__, ZTEBLADEFM_PIPE_STATUS); } } #if __t0mm13b_defiant__ int rv = mkfifo(ZTEBLADEFM_PIPE_CMD, 0666); if (rv < 0) { // handle condition here.. panic("[%s:tune_in(...) @ %d] - Could not mkfifo %s.", __FILE__, __LINE__, ZTEBLADEFM_PIPE_CMD); } rv = mkfifo(ZTEBLADEFM_PIPE_STATUS, 0666); if (rv < 0) { // handle condition here.. panic("[%s:tune_in(...) @ %d] - Could not mkfifo %s.", __FILE__, __LINE__, ZTEBLADEFM_PIPE_STATUS); } #else g_rdfmdev = open(FM_DEV, O_RDONLY); #endif // init_open_statuspipe(); init_open_commandpipe(); // logic routine from here ... http://stackoverflow.com/questions/1735781/non-blocking-pipe-using-popen while (g_keepRunning) { selfd = select(FD_SETSIZE, &g_fdset_r, (fd_set*)0, (fd_set*)0,NULL); if (selfd < 0) panic("Could not select..."); if (selfd > 0) { check_select(); } } if (g_fprdcmdpipe != NULL) fclose(g_fprdcmdpipe); if (g_fpwrstatpipe != NULL) fclose(g_fpwrstatpipe); #ifdef __t0mm13b_defiant__ ; #else close(g_rdfmdev); #endif cleanup_regexps(); // END HERE }
bool client_connection::connect_to( const std::string& server, unsigned short port, long timeout_sec ) { socket_ = ::socket( AF_INET, SOCK_STREAM, 0 ); if( socket_ == INVALID_SOCKET ) { return false; } SOCKADDR_IN sock_addr; sock_addr.sin_family = AF_INET; sock_addr.sin_port = ::htons( port ); sock_addr.sin_addr.s_addr = ::inet_addr( server.c_str() ); if( sock_addr.sin_addr.s_addr == INADDR_NONE ) { // 일단 IPv4만 생각한다. std::vector< std::string > ips = get_host_ips( server ); if( ips.empty() == false ) { sock_addr.sin_addr.s_addr = ::inet_addr( ips.front().c_str() ); } else { close(); return false; } } // start non-blocking mode for socket: unsigned long ul = 1; if( ::ioctlsocket( socket_, FIONBIO, &ul ) == SOCKET_ERROR ) { close(); return false; } if( ::connect( socket_, (LPSOCKADDR)&sock_addr, sizeof( sock_addr ) ) == SOCKET_ERROR ) { if( ::WSAGetLastError() != WSAEWOULDBLOCK ) { close(); return false; } if( check_select( socket_, false, true, timeout_sec ) == false ) { close(); return false; } } return true; }
void do_read(ev::io& w, int revents) { /*now attempt the read*/ /*first use a select() to check: the event loop might falsely trigger */ if((revents & ev::READ) && check_select(ev::READ)) { /*now attempt a read*/ ioa.data.reset( new std::vector<unsigned char>(READ_SIZE)); ssize_t rv = read(fd, io.data->begin(), READ_SIZE); if(rv < 0) { /*potential errors*/ switch(errno) { /*ignore these*/ case EAGAIN: case EINTR: return; break; case EBADF: todo.err(ioa, "not valid, or not " "open for reading"); break; case EFAULT: todo.err(ioa, "internal error, buffer " "misallocated"); break; case EINVAL: todo.err(ioa, "unsuitable for " "reading"); break; case EIO: todo.err(ioa, "low-level i/o error"); break; default: todo.err(ioa, "unknown error type"); break; } } else if(rv == 0) { todo.eof(ioa); } else { ioa.data->resize(rv); todo.respond(ioa); } w.stop(); } }
int get_db_info(t_game_goodies *nfo) { t_trame trame; Uint32 ticks; int ret; ticks = SDL_GetTicks(); stock_msg(&cnt->clients[0], TAG_WELCOME, 0, NULL); fprintf(fd_log, "in\n"); while (42) { if ((ret = check_select(100))) { if (exec_msg(&cnt->clients[0], &trame)) { if (is_valid_trame(&trame, TAG_WELCOME)) { fprintf(fd_log, "AFirstChaos: Coucou from server\n"); } else if (is_valid_trame(&trame, TAG_INFO)) { memcpy((void*)nfo->db_info, trame.msg, sizeof(*(nfo->db_info))); free(trame.msg); fprintf(fd_log, "out\n"); return (0); } else fprintf(fd_log, "AFirstChaos: Trame unused: %d\n", trame.tag); } else fprintf(fd_log, "Activity from ? (%d)\n", ret); } if (!cnt->clients[0].sock) return (1); if ((SDL_GetTicks() - ticks) > (50000 * SEC_IN_MS)) { fprintf(fd_log, "drop out\n"); return (1); } } return (1); }
int init_players_for_game(t_engine *e, int who) { t_tmp *list; t_tmp *next; int i; t_info_player info_player; e->assos_clients[0] = 0; info_player.id_player = 0; stock_msg(&(cnt->clients[0]), TAG_PLAYER_INFO, sizeof(info_player), &info_player); init_player(&e->players[0]); i = 1; if (who == HOME) { //while (i < 2) //{ check_select(1000); for (list = cnt->newclient; list; list = next) { next = list->next; //if (list->state == STATE_PLAYER) //{ cnt->clients = (t_client*)xrealloc(cnt->clients, sizeof(*cnt->clients) * (i + 2)); memcpy(&cnt->clients[i], &list->c, sizeof(list->c)); e->assos_clients[i] = i; info_player.id_player = i; stock_msg(&(cnt->clients[i]), TAG_PLAYER_INFO, sizeof(info_player), &info_player); fprintf(fd_log, "find one client\n"); cnt->newclient = del_in_list(cnt->newclient, &list->c); i++; //} } init_client(&cnt->clients[i]); //} } e->nb_players = i; return (0); }
int normal_stream::recv( void* buffer, int size, long timeout_sec ) { if( buffer == NULL || size < 0 ) { return 0; } if( check_select( socket_, true, false, timeout_sec ) == false ) { return 0; } char* temp_buffer = reinterpret_cast< char* >( buffer ); int res = ::recv( socket_, temp_buffer, size, 0 ); if( res == SOCKET_ERROR ) { return 0; } return res; }
// Start Of Program - this is where we setup everything before getting into the main loop void main(void) { // Oscillator setup OSCCON = 0b11100000; // device enters idle on Sleep(), 8Mhz Clock, OSCTUNE = 0b00000000; // Internal oscillator low freq comes from 31Khz clock from LFINTOSC, PLL disabled // Analog / Digital pins setup ANSEL = 0b00000000; // disable all analog inputs (make them all digital) must do this! ANSELH = 0b00000000; // disable all analog inputs (make them all digital) must do this! // Tristate setup TRISA = 0b00000011; TRISB = 0b11111110; TRISC = 0b00000000; TRISD = 0b00000000; TRISE = 0b00000000; // configure TIMER2: // prescaler 16, period register for 1ms, timer stopped T2CON = 0b00000010; TMR2 = 0; PR2 = _XTAL_FREQ / 1000 / 16 / 4; // initialize subsystems btn_init(); init_all(); // disable INT1, config for raising endge INT1IE = 0; INTEDG1 = 1; // enable interrupts TMR2IE = 1; // TIMER2 interrupt PEIE = 1; // peripheral interrupt GIE = 1; // global interrupt enable // start TIMER2 TMR2ON = 1; // main loop while (true) { off_flag = false; // go to idle and wait for timer Sleep(); // read button inputs btn_update(); // check for commands check_select(); check_off(); check_idle(); // execute mode task switch (mode) { case modeSelect: mode_select(); break; case modeSparkle: sparkle_leds(); break; case modeShiftReg: shiftreg_task(); break; case modeLightTest: led_group(LED_ALL, true); break; case modePOV: povmsg_task(); break; case modeBinDice: case modeDecDice: dice_task(mode == modeDecDice); break; case modeGame: game_task(); break; case mode4BitLogic: logic_4bit_task(); break; default: logic_task(); flipflop_task(); counter_task(mode == modeGrayCnt); } if (off_flag) { switch_off(); } } }
int before_starting_game(t_engine *e, t_game_param *game_param) { t_trame *req; int who_serve; int send; int update_param; // //considere que le jeu cree une partie tout seul: // printf("before start\n"); // fflush(fd_log); return (HOME); // TODO: TOUT ca a revoir une fois l'interface du menu defini: fprintf(fd_log, "Loading menu...\n"); // if (run_menu(gfx->win)) // { // fprintf(fd_log, "%s: Quitting game...\n", NAME); // return (ERROR); // } req = (t_trame*)xmalloc(sizeof(*req)); for (who_serve = NONE, send = 0, update_param = 0; 42; send = 0, update_param = 0) /* < va gerer les requetes que va envoyer le jeu pour la creation de partie jusque a le lancemant de la partie; et les requetes des autres moteur.*/ { printf("ESSAI\n");fflush(stdout); fflush(fd_log); if (check_select(10000)) { // TODO: mettre tout ca dans les process..() // (speciaux pour les menus ptet) // printf("DEDAN\n");fflush(stdout); // if (exec_msg(&cnt->clients[0], req)) // { // if (is_valid_trame(req, TAG_JOIN)) // { // join_game(req); // // send_hash5_to_server(); // une // //if (!ok) // seule // // upgrade_BDD; // fois // // get_game_param_from_server(req, game_param); // who_serve = REMOTE; // // send_to_all_player_new_game_status(game_param); // // ^ envoi au client local les parametre de la partie // } // else if (is_valid_trame(req, TAG_CREATE)) // { // // init_game_param(game_param, req, (t_pos*)&pos); // who_serve = HOME; // // send_to_all_player_new_game_status(game_param); // } // // else if (who_serve && is_valid_trame(req, TAG_LAUNCH_GAME)) // // return (who_serve); // else if (who_serve == HOME) // //rentre ici quand le jeu est server. // { // /* GERAGE DES CONNECTIONS */ // // server_connections(game_param, (t_pos*)&pos); // if (is_valid_trame(req, TAG_LAUNCH_GAME)) // { // t_tmp *list; // for (list = cnt->newclient; list; list = list->next) // stock_msg(&list->c, TAG_LAUNCH_GAME, 0, NULL); // // move_clients_to_players(e, game_param); // return (who_serve); // } // /* GERAGE DE LA REQUETE */ // // if (update_game_param(req, game_param, pos) || // // va gerer les changements de param // // ot_chose()) || //finctions qui va gerer les autres requetes // // send_to_all_player_new_game_status(game_param)) // // return (put_error("trame gerage failed")); // if (is_valid_trame(req, TAG_LEAVE)) // who_serve = NONE; // } // else if (who_serve == REMOTE) // { // // verifier que l'on soit tjrs connecter au server // if (cnt->server.sock) // who_serve = NONE; // // if (cnt->last_recv->sock == cnt->server.sock && // // is_valid_trame(req, TAG_GAME_STATUS)) // // { // // if (copy_game_param(req, game_param)) // // return (put_error("update_game_param failed")); // // } // // else if (cnt->last_recv->sock == cnt->clients[0].sock && // // is_valid_trame(req, TAG_GP_PLAYERS)) // // { // // if (send_to_all_player_new_game_status(game_param)) // // return (put_error("send_to_all_player_new_game_status failed")); // // } // if (is_valid_trame(req, TAG_LEAVE)) // who_serve = NONE; // } // } // else // { // t_tmp *list; // printf("DANS LE ELSE\n");fflush(stdout); // for (list = cnt->newclient; list; list = list->next) // { // if (exec_msg(&list->c, req)) // { // if (is_valid_trame(req, TAG_JOIN)) // { // fprintf(fd_log, "un joueur est la\n"); // list->state = STATE_PLAYER; // return (HOME); // } // else // fprintf(fd_log, "un nouveau client me parle :%d.. alors qu'il devrait attendre" // "sagement\n", req->tag); // } // } // fprintf(fd_log, "les autres joueurs parlent\n"); // // d'autres requetes ? (READY...) // } } } return (ERROR); }
/* * Verify that: * - a nonblocking connecting socket for which there is no accepter, will * return EINPROGRESS and complete in the background later; * - a nonblocking listening socket will return EAGAIN on accept; * - connecting a connecting socket yields EALREADY; * - connecting a connected socket yields EISCONN; * - selecting for read and write on a connecting socket will only satisfy the * write only once it is connected; * - doing a nonblocking write on a connecting socket yields EAGAIN; * - doing a nonblocking read on a connected socket with no pending data yields * EAGAIN. */ void test_nonblock(const struct socket_test_info *info) { char buf[BUFSIZE]; socklen_t len; int server_sd, client_sd; struct sockaddr_storage addr; int status, on; debug("entering test_nonblock()"); memset(buf, 0, sizeof(buf)); SOCKET(server_sd, info->domain, info->type, 0); on = 1; (void)setsockopt(server_sd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); if (bind(server_sd, info->serveraddr, info->serveraddrlen) == -1) test_fail("bind() should have worked"); if (info->callback_set_listen_opt != NULL) info->callback_set_listen_opt(server_sd); if (listen(server_sd, 8) == -1) test_fail("listen() should have worked"); fcntl(server_sd, F_SETFL, fcntl(server_sd, F_GETFL) | O_NONBLOCK); check_select(server_sd, 0 /*read*/, 1 /*write*/, 0 /*block*/); len = sizeof(addr); if (accept(server_sd, (struct sockaddr *) &addr, &len) != -1 || errno != EAGAIN) test_fail("accept() should have yielded EAGAIN"); SOCKET(client_sd, info->domain, info->type, 0); fcntl(client_sd, F_SETFL, fcntl(client_sd, F_GETFL) | O_NONBLOCK); if (connect(client_sd, info->clientaddr, info->clientaddrlen) != -1) { test_fail("connect() should have failed"); } else if (errno != EINPROGRESS) { test_fail("connect() should have yielded EINPROGRESS"); } check_select_cond(client_sd, 0 /*read*/, 0 /*write*/, 0 /*block*/, !info->ignore_select_delay); if (connect(client_sd, info->clientaddr, info->clientaddrlen) != -1) { test_fail("connect() should have failed"); } else if (errno != EALREADY && errno != EISCONN) { test_fail("connect() should have yielded EALREADY"); } if (recv(client_sd, buf, sizeof(buf), 0) != -1 || errno != EAGAIN) test_fail("recv() should have yielded EAGAIN"); /* This may be an implementation aspect, or even plain wrong (?). */ if (!info->ignore_send_waiting) { if (send(client_sd, buf, sizeof(buf), 0) != -1) { test_fail("send() should have failed"); } else if (errno != EAGAIN) { test_fail("send() should have yielded EAGAIN"); } } switch (fork()) { case 0: errct = 0; close(client_sd); check_select(server_sd, 1 /*read*/, 1 /*write*/, 0 /*block*/); len = sizeof(addr); client_sd = accept(server_sd, (struct sockaddr *) &addr, &len); if (client_sd == -1) test_fail("accept() should have succeeded"); check_select(server_sd, 0 /*read*/, 1 /*write*/, 0 /*block*/); close(server_sd); /* Let the socket become writable in the parent process. */ sleep(1); if (write(client_sd, buf, 1) != 1) test_fail("write() should have succeeded"); /* Wait for the client side to close. */ check_select_cond(client_sd, 0 /*read*/, 1 /*write*/, 0 /*block*/, !info->ignore_select_delay /*allchecks*/); check_select(client_sd, 1 /*read*/, -1 /*write*/, 1 /*block*/); check_select(client_sd, 1 /*read*/, 1 /*write*/, 0 /*block*/); exit(errct); case -1: test_fail("can't fork"); default: break; } close(server_sd); check_select(client_sd, 0 /*read*/, 1 /*write*/, 1 /*block*/); check_select(client_sd, 0 /*read*/, 1 /*write*/, 0 /*block*/); if (connect(client_sd, info->clientaddr, info->clientaddrlen) != -1 || errno != EISCONN) test_fail("connect() should have yielded EISCONN"); check_select(client_sd, 1 /*read*/, -1 /*write*/, 1 /*block*/); check_select(client_sd, 1 /*read*/, 1 /*write*/, 0 /*block*/); if (read(client_sd, buf, 1) != 1) test_fail("read() should have succeeded"); check_select(client_sd, 0 /*read*/, 1 /*write*/, 0 /*block*/); if (read(client_sd, buf, 1) != -1 || errno != EAGAIN) test_fail("read() should have yielded EAGAIN"); /* Let the child process block on the select waiting for the close. */ sleep(1); close(client_sd); errno = 0; if (wait(&status) <= 0) test_fail("wait() should have succeeded"); if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) test_fail("child process failed the test"); info->callback_cleanup(); debug("leaving test_nonblock()"); }
int main(int ac, char **av) { // doit absolument etre apelle avant d'autres appels a la lib init_nettool(); if (ac > 1) // server mode { // set handlers assign_newclient(process_newclient, NULL); assign_deadclient(process_deadclient, NULL); assign_clients(process_clients, NULL); // open listen connection if (init_server_connection(PORT)) return (1); // check messages while (1) check_select(MAXSELECT); // close connection close_server_connection(); close_connection(); } else // client mode { // connect to server if (init_connection("localhost", PORT)) return (1); assign_deadclient(process_drop, NULL); printf("step 1\n");fflush(stdout); fflush(stdout); // stock messages to send stock_remote_msg(WELCOME, strlen("tata"), (void*)"tata"); printf("step 2\n");fflush(stdout); fflush(stdout); stock_remote_msg(HELLOWORLD, 0, NULL); printf("step 3\n");fflush(stdout); fflush(stdout); stock_remote_msg(HELLOWORLD, 0, NULL); printf("step 4\n");fflush(stdout); fflush(stdout); stock_remote_msg(HELLOWORLD, 0, NULL); printf("step 5\n");fflush(stdout); fflush(stdout); stock_remote_msg(HELLOWORLD, 0, NULL); printf("step 5\n");fflush(stdout); fflush(stdout); printf("step 7\n");fflush(stdout); fflush(stdout); // send messages while (1) check_select(MAXSELECT); printf("step 8\n");fflush(stdout); fflush(stdout); // close connection close_connection(); printf("step 9\n");fflush(stdout); fflush(stdout); } // free memory, and close connections nettool_quit(); if (players) free(players); return (0); }
/* * Verify that: * - interrupting a blocking connect will return EINTR but complete in the * background later; * - doing a blocking write on an asynchronously connecting socket succeeds * once the socket is connected. * - doing a nonblocking write on a connected socket with lots of pending data * yields EAGAIN. */ void test_intr(const struct socket_test_info *info) { struct sigaction act, oact; char buf[BUFSIZE]; int isconn; socklen_t len; int server_sd, client_sd; struct sockaddr_storage addr; int r, status, on; debug("entering test_intr()"); memset(buf, 0, sizeof(buf)); SOCKET(server_sd, info->domain, info->type, 0); on = 1; (void)setsockopt(server_sd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); if (bind(server_sd, info->serveraddr, info->serveraddrlen) == -1) test_fail("bind() should have worked"); if (info->callback_set_listen_opt != NULL) info->callback_set_listen_opt(server_sd); if (listen(server_sd, 8) == -1) test_fail("listen() should have worked"); SOCKET(client_sd, info->domain, info->type, 0); memset(&act, 0, sizeof(act)); act.sa_handler = dummy_handler; if (sigaction(SIGALRM, &act, &oact) == -1) test_fail("sigaction() should have succeeded"); if (info->domain != PF_INET) alarm(1); isconn = 0; if (connect(client_sd, info->clientaddr, info->clientaddrlen) != -1) { if (!info->ignore_connect_unaccepted) { test_fail("connect() should have failed"); } isconn = 1; } else if (errno != EINTR) { test_fail("connect() should have yielded EINTR"); } alarm(0); check_select(client_sd, 0 /*read*/, isconn /*write*/, 0 /*block*/); switch (fork()) { case 0: errct = 0; close(client_sd); /* Ensure that the parent is blocked on the send(). */ sleep(1); check_select(server_sd, 1 /*read*/, 1 /*write*/, 0 /*block*/); len = sizeof(addr); client_sd = accept(server_sd, (struct sockaddr *) &addr, &len); if (client_sd == -1) test_fail("accept() should have succeeded"); check_select(server_sd, 0 /*read*/, 1 /*write*/, 0 /*block*/); close(server_sd); check_select(client_sd, 1 /*read*/, -1 /*write*/, 1 /*block*/); check_select(client_sd, 1 /*read*/, 1 /*write*/, 0 /*block*/); if (recv(client_sd, buf, sizeof(buf), 0) != sizeof(buf)) test_fail("recv() should have yielded bytes"); /* No partial transfers should be happening. */ check_select(client_sd, 0 /*read*/, 1 /*write*/, 0 /*block*/); sleep(1); fcntl(client_sd, F_SETFL, fcntl(client_sd, F_GETFL) | O_NONBLOCK); /* We can only test nonblocking writes by filling the pipe. */ while ((r = write(client_sd, buf, sizeof(buf))) > 0); if (r != -1) { test_fail("write() should have failed"); } else if (errno != EAGAIN) { test_fail("write() should have yielded EAGAIN"); } check_select(client_sd, 0 /*read*/, 0 /*write*/, 0 /*block*/); if (write(client_sd, buf, 1) != -1) { test_fail("write() should have failed"); } else if (errno != EAGAIN) { test_fail("write() should have yielded EAGAIN"); } exit(errct); case -1: test_fail("can't fork"); default: break; } close(server_sd); if (send(client_sd, buf, sizeof(buf), 0) != sizeof(buf)) test_fail("send() should have succeded"); check_select(client_sd, 0 /*read*/, 1 /*write*/, 0 /*block*/); if (wait(&status) <= 0) test_fail("wait() should have succeeded"); if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) test_fail("child process failed the test"); check_select(client_sd, 1 /*read*/, 1 /*write*/, 0 /*block*/); close(client_sd); sigaction(SIGALRM, &oact, NULL); info->callback_cleanup(); debug("leaving test_intr()"); }