Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
0
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()");
}
Exemplo n.º 7
0
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
}
Exemplo n.º 8
0
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;
}
Exemplo n.º 9
0
Arquivo: ev.cpp Projeto: AmkG/snap
	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();
		}
	}
Exemplo n.º 10
0
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);
}
Exemplo n.º 12
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;
}
Exemplo n.º 13
0
// 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()");
}