Exemplo n.º 1
0
static int handle_set_key_cmd(SOCKET sock, struct sync_device *data)
{
	uint32_t track, row;
	union {
		float f;
		uint32_t i;
	} v;
	struct track_key key;
	unsigned char type;

	if (xrecv(sock, (char *)&track, sizeof(track), 0) ||
	    xrecv(sock, (char *)&row, sizeof(row), 0) ||
	    xrecv(sock, (char *)&v.i, sizeof(v.i), 0) ||
	    xrecv(sock, (char *)&type, 1, 0))
		return -1;

	track = ntohl(track);
	v.i = ntohl(v.i);

	key.row = ntohl(row);
	key.value = v.f;

	assert(type < KEY_TYPE_COUNT);
	assert(track < data->num_tracks);
	key.type = (enum key_type)type;
	return sync_set_key(data->tracks[track], &key);
}
Exemplo n.º 2
0
int sync_update(struct sync_device *d, int row, struct sync_cb *cb,
    void *cb_param)
{
	if (d->sock == INVALID_SOCKET)
		return -1;

	/* look for new commands */
	while (socket_poll(d->sock)) {
		unsigned char cmd = 0, flag;
		uint32_t new_row;
		if (xrecv(d->sock, (char *)&cmd, 1, 0))
			goto sockerr;

		switch (cmd) {
		case SET_KEY:
			if (handle_set_key_cmd(d->sock, d))
				goto sockerr;
			break;
		case DELETE_KEY:
			if (handle_del_key_cmd(d->sock, d))
				goto sockerr;
			break;
		case SET_ROW:
			if (xrecv(d->sock, (char *)&new_row, sizeof(new_row), 0))
				goto sockerr;
			if (cb && cb->set_row)
				cb->set_row(cb_param, ntohl(new_row));
			break;
		case PAUSE:
			if (xrecv(d->sock, (char *)&flag, 1, 0))
				goto sockerr;
			if (cb && cb->pause)
				cb->pause(cb_param, flag);
			break;
		case SAVE_TRACKS:
			sync_save_tracks(d);
			break;
		default:
			fprintf(stderr, "unknown cmd: %02x\n", cmd);
			goto sockerr;
		}
	}

	if (cb && cb->is_playing && cb->is_playing(cb_param)) {
		if (d->row != row && d->sock != INVALID_SOCKET) {
			unsigned char cmd = SET_ROW;
			uint32_t nrow = htonl(row);
			if (xsend(d->sock, (char*)&cmd, 1, 0) ||
			    xsend(d->sock, (char*)&nrow, sizeof(nrow), 0))
				goto sockerr;
			d->row = row;
		}
	}
	return 0;

sockerr:
	closesocket(d->sock);
	d->sock = INVALID_SOCKET;
	return -1;
}
Exemplo n.º 3
0
int		init_download(client_ftp_t *client_ftp, char *cmd)
{
  char		buff[1024];
  int		i;

  bzero(buff, 1024);
  xsend(client_ftp->s, "TYPE I\n", 7, 0);
  i = xrecv(client_ftp->s, buff, 1024, 0);
  clean_buff(buff, i);
  printf("%s\n", buff);
  bzero(buff, 1024);
  open_new_data_connection(client_ftp);
  open_data_connection(client_ftp);
  bzero(buff, 1024);
  for (i = 4; cmd[i] == ' ' && cmd[i] != '\0'; i++)
    ;
  sprintf(buff, "RETR %s\n", cmd + i);
  xsend(client_ftp->s, buff, strlen(buff), 0);
  i = xrecv(client_ftp->s, buff, 1024, 0);
  clean_buff(buff, i);
  printf("%s\n", buff);
  if (strncmp(buff, "550", 3) == 0)
    {
      close(client_ftp->s_data);
      return (1);
    }
  return (0);
}
Exemplo n.º 4
0
static int handle_del_key_cmd(SOCKET sock, struct sync_device *data)
{
	uint32_t track, row;

	if (xrecv(sock, (char *)&track, sizeof(track), 0) ||
	    xrecv(sock, (char *)&row, sizeof(row), 0))
		return -1;

	track = ntohl(track);
	row = ntohl(row);

	assert(track < data->num_tracks);
	return sync_del_key(data->tracks[track], row);
}
Exemplo n.º 5
0
Arquivo: poll_ts.c Projeto: tniuli/xio
int main (int argc, char **argv)
{
	int i, j;
	char *ubuf = 0;
	int afd, sfd, tmp;
	thread_t cli_thread = {};

	BUG_ON ( (afd = xlisten ("tcp+ipc+inproc://127.0.0.1:18897") ) < 0);
	thread_start (&cli_thread, xclient_thread, 0);
	usleep (100000);
	BUG_ON (xselect (XPOLLIN, 1, &afd, 1, &tmp) <= 0);
	for (j = 0; j < 3; j++) {
		BUG_ON ( (sfd = xaccept (afd) ) < 0);
		for (i = 0; i < cnt; i++) {
			while (xselect (XPOLLIN, 1, &sfd, 1, &tmp) <= 0)
				usleep (10000);
			BUG_ON (tmp != sfd);
			BUG_ON (0 != xrecv (sfd, &ubuf) );
			BUG_ON (0 != xsend (sfd, ubuf) );
		}
		xclose (sfd);
	}
	thread_stop (&cli_thread);
	xclose (afd);
	return 0;
}
Exemplo n.º 6
0
void		retr_opt(client_ftp_t *client_ftp, char *cmd)
{
  FILE		*fs;
  char		buff[1024];
  char		put[1024];
  int		nb;
  int		i;
  int		j;

  if ((i = init_download(client_ftp, cmd)) == 1)
    return;
  if ((fs = fopen(cmd + 4, "w+")) == NULL)
    {
      printf("Failed to open file\n");
      close(client_ftp->s_data);
      return;
    }
  bzero(buff, 1024);
  while ((nb = xread(client_ftp->s_data, buff, 1024)))
    {
      bzero(put, 1024);
      for (i = 0, j = 0; i != nb; i++, j++)
	put[j] = buff[i];
      fwrite(put, 1, j, fs);
      bzero(buff, 1024);
    }
  fclose(fs);
  i = xrecv(client_ftp->s, buff, 1024, 0);
  clean_buff(buff, i);
  printf("%s\n", buff);
  close(client_ftp->s_data);
}
Exemplo n.º 7
0
void	get_client(t_ftp *f)
{
  t_cmd	c;
  char	buf[1024];
  int	nbr;
  int	pid;

  if (DEBUG)
    printf("get_client()\n");
  if (!(pid = fork()))
    {
      f->cnt = FALSE;
      bzero(buf, sizeof(buf));
      mesg_start(f);
      while ((nbr = (int) xrecv(f->cs, buf, (void *) sizeof(buf), 0)) > 0)
	{
	  if (cmd_init(&c, f, trim(buf)) == TRUE)
	    if (req_init(&c) == RET_QUIT)
	      break;
	  bzero(buf, sizeof(buf));
	}
      close(f->cs);
      exit(0);
    }
}
Exemplo n.º 8
0
void		client_read(t_info *info, t_client **client)
{
  int		r;
  char		buf[BUF_SIZE + 1];
  char		buff_perso[BUF_SIZE + 1];
  char		*p;
  t_client	*check_respaw;

  if ((r = (int)xrecv((*client)->socket, buf, BUF_SIZE, 0)) > 0)
    {
      buf[r] = '\0';
      strncat((*client)->buf_read, buf, BUF_SIZE - strlen(buf));
      while ((p = strstr((*client)->buf_read, "\n")))
	{
	  *p = 0;
	  strncpy(buff_perso, (*client)->buf_read, BUF_SIZE - 1);
	  check_respaw = *client;
	  if ((*client)->status < ST_CLIENT)
	    begin_session(info, client);
	  else
	    execute_action(buff_perso, *client, info);
	  if (check_respaw == *client)
	    memmove((*client)->buf_read, p + 1, BUF_SIZE);
	}
    }
  else
    client_disconnect((*client), info);
}
Exemplo n.º 9
0
static SOCKET server_connect(const char *host, unsigned short nport)
{
	struct hostent *he;
	char **ap;

#ifdef WIN32
	static int need_init = 1;
	if (need_init) {
		WSADATA wsa;
		if (WSAStartup(MAKEWORD(2, 0), &wsa))
			return INVALID_SOCKET;
		need_init = 0;
	}
#elif defined(USE_AMITCP)
	if (!socket_base) {
		socket_base = OpenLibrary("bsdsocket.library", 4);
		if (!socket_base)
			return INVALID_SOCKET;
	}
#endif

	he = gethostbyname(host);
	if (!he)
		return INVALID_SOCKET;

	for (ap = he->h_addr_list; *ap; ++ap) {
		SOCKET sock;
		struct sockaddr_in sa;

		sa.sin_family = he->h_addrtype;
		sa.sin_port = htons(nport);
		memcpy(&sa.sin_addr, *ap, he->h_length);
		memset(&sa.sin_zero, 0, sizeof(sa.sin_zero));

		sock = socket(he->h_addrtype, SOCK_STREAM, 0);
		if (sock == INVALID_SOCKET)
			continue;

		if (connect(sock, (struct sockaddr *)&sa, sizeof(sa)) >= 0) {
			char greet[128];

			if (xsend(sock, CLIENT_GREET, strlen(CLIENT_GREET), 0) ||
				xrecv(sock, greet, strlen(SERVER_GREET), 0)) {
				closesocket(sock);
				continue;
			}

			if (!strncmp(SERVER_GREET, greet, strlen(SERVER_GREET)))
				return sock;
		}

		closesocket(sock);
	}

	return INVALID_SOCKET;
}
Exemplo n.º 10
0
void		init_pwd(client_ftp_t *client_ftp)
{
  char		buffer[1024];
  int		i;

  bzero(buffer, 1024);
  xsend(client_ftp->s, "PWD\n", 4, 0);
  i = xrecv(client_ftp->s, buffer, 1024, 0);
  clean_buff(buffer, i);
  client_ftp->pwd = strdup(buffer);
}
Exemplo n.º 11
0
	void*
ServiceThread(void* args)
{
	thread_data_t* ptd = (thread_data_t*)args;
	int sock = -1;
	int ret = -1;
	int netret = -1;
	socklen_t   caddr_len=0;

	ROUTN( "ServiceThread[%u] Create OK", ptd->tid);

	while( 1 )
	{
		netret = -1;
		ret = -1;
        sock = ptd->poll->fetch_socket();
		if( sock>0 ){
            sockaddr_in cltaddr;
            caddr_len = sizeof(cltaddr);
            getpeername(sock, (sockaddr*)&cltaddr, &caddr_len );
            inet_ntop(AF_INET, (void *)&cltaddr.sin_addr, ptd->cltip, sizeof(ptd->cltip));
        }
        else
        {
            ALARM( "sock:%d %m", sock );
            continue;
        }

        memset (ptd->RecvHead, 0, sizeof(ptd->RecvHead));
        netret = xrecv(sock, ptd->RecvHead, ptd->RecvBuffSize, myConfig->RTimeMS());
        if( netret <0 && errno != EAGAIN)
        {
            DEBUG( "xrecv error. sock:%d ret:%d name:%s body_len:%d to[%u] errno[%d] msg[%m]",
                    sock, netret, ptd->RecvHead->srvname,ptd->RecvHead->detail_len,
                    myConfig->RTimeMS(), errno);
            ptd->poll->free_socket(sock, 0);
            continue;
        }
        else
        {
            ret = (ptd->servapp)( ptd );
            netret = xsend(sock, ptd->SendHead, myConfig->WTimeMS());
            if(( netret<0 || ret<0 ) && errno != EAGAIN){
                DEBUG( "xsend error. sock:%d netret:%d ret:%d errno[%d] %m", sock, netret, ret, errno );
                ptd->poll->free_socket(sock, 0);
                continue;
            }
        }
        ptd->poll->free_socket(sock, 1);
    }
    return NULL;
}
Exemplo n.º 12
0
static int	recv_welcome(t_info *info)
{
  int	nbr;

  info->buf[0] = 0;
  if ((nbr = xrecv(info->socket, info->buf, BUF_SIZE, 0)) > 0)
    {
      info->buf[nbr] = 0;
      if (strncmp(MSG_WELCOME, info->buf, strlen(MSG_WELCOME)))
	return (-1);
    }
  return (0);
}
Exemplo n.º 13
0
static int	loop(t_info *info, char **buf)
{
  int		nbr;

  if (!(*buf)[0])
    {
      if (!(nbr = xrecv(info->socket, info->buf,
			BUF_SIZE, 0)))
	return (-1);
      info->buf[nbr] = 0;
      *buf = info->buf;
    }
  while (!strncmp(*buf, ADD_CLIENT, strlen(ADD_CLIENT)))
    {
      skip_from_buf(buf);
      add_client(info, buf);
    }
  return (0);
}
Exemplo n.º 14
0
void	client_listen(t_ftp *f)
{
  char	buf[1024];
  int	nbr;

  if (DEBUG)
    printf("client_listen()\n");
  while (42)
    {
      bzero(buf, sizeof(buf));
      if ((nbr = (int) xrecv(f->s, buf, (void *) sizeof(buf), 0)) > 0)
	{
	  if (is_get(f, buf) == FALSE)
	    write(1, buf, nbr);
	}
      else
	break;
      prompt();
    }
  printf("connection stopped\n");
  exit(TRUE);
}
Exemplo n.º 15
0
Arquivo: poll_ts.c Projeto: tniuli/xio
static void xclient (const char *pf)
{
	int sfd, i;
	int64_t nbytes;
	char buf[1024] = {};
	char *ubuf;
	char host[1024] = {};

	sprintf (host, "%s%s", pf, "://127.0.0.1:18897");
	randstr (buf, 1024);
	BUG_ON ( (sfd = xconnect (host) ) < 0);
	for (i = 0; i < cnt; i++) {
		nbytes = rand() % 1024;
		ubuf = ubuf_alloc (nbytes);
		memcpy (ubuf, buf, nbytes);
		BUG_ON (0 != xsend (sfd, ubuf) );
		BUG_ON (0 != xrecv (sfd, &ubuf) );
		DEBUG_OFF ("%d recv response", sfd);
		assert (memcmp (ubuf, buf, nbytes) == 0);
		ubuf_free (ubuf);
	}
	xclose (sfd);
}
Exemplo n.º 16
0
int
main (int argc, char **argv) {
  int err;
  char *srvr_addr = NULL;
  int port_num;
  int len_inet;			/* length  */
  int sockfd;			/* Socket */

  if (argc == 4) {
	  srvr_addr = argv[1];
	  port_num = atoi(argv[2]);
  } else {
	  printf("usage:%s dst_ip dst_port cicle\n", argv[0]);
	  bail("try again!");
  }

  struct sockaddr_in adr_srvr;	/* AF_INET */
  len_inet = sizeof adr_srvr;
  memset (&adr_srvr, 0, len_inet);
  adr_srvr.sin_family = AF_INET;
  adr_srvr.sin_port = htons (port_num);
  adr_srvr.sin_addr.s_addr = inet_addr (srvr_addr);

  if (adr_srvr.sin_addr.s_addr == INADDR_NONE) {
	  bail ("bad address.");
  }

  sockfd = socket (PF_INET, SOCK_STREAM, 0);
  if (sockfd == -1) bail ("socket()");

  err = connect (sockfd, (struct sockaddr *) &adr_srvr, len_inet);
  if (err == -1) bail ("connect(2)");

  int logid = 0;
  char reqbuff[100000];
  char resbuff[100000];
  memset (reqbuff, 0, sizeof(reqbuff));
  memset (resbuff, 0, sizeof(resbuff));
  xhead_t* reqxhead = (xhead_t*) reqbuff;
  xhead_t* resxhead = (xhead_t*) resbuff;

  char input[1024];
  while (fgets(input, sizeof(input), stdin))
  {
      snprintf(reqxhead->srvname, sizeof(reqxhead->srvname), "%s", "myclient");
      char* str = (char*)(reqxhead+1);
      input[strlen(input) - 1] = 0;
      strncpy(str, input, 1000);
      reqxhead->detail_len = strlen(str) + 1;

      int count = atoi(argv[3]);
      for (int i=0; i<count; i++)
      {
          reqxhead->log_id = logid++;
          int ret = 0;
          if (0 != (ret = xsend(sockfd, reqxhead, 1000)))
          {
              fprintf(stderr, "send err ret[%d] ind[%d] errno[%d] [%m]\n", ret, i, errno);
              exit(1);
          }
          memset(resxhead, 0, 100000);
          if (0 != (ret = xrecv(sockfd, resxhead, sizeof(resbuff), 1000)))
          {
              fprintf(stderr, "recv err ret[%d] ind[%d] errno[%d] [%m]\n", ret, i, errno);
              exit(1);
          }
          else
          {
              printf ("count[%u] ind[%04u] rslen[%d] logid[%u] name[%s] message[%s]\n",
                      count, i, resxhead->detail_len,resxhead->log_id, resxhead->srvname, (char*)&resxhead[1]);
          }
      }
//      for (int i=0; i<count; i++)
//      {
//          int ret = 0;
//          if (0 != (ret = xrecv(sockfd, resxhead, sizeof(resbuff), 1000)))
//          {
//              fprintf(stderr, "recv err ret[%d] ind[%d] [%m]\n", ret, i);
//              exit(1);
//          }
//          else
//          {
//              str = (char*) (resxhead+1);
////              printf ("count[%u] ind[%04u] rslen[%d] logid[%u] name[%s] message[%s]\n",
////                      count, i, resxhead->detail_len,resxhead->log_id, resxhead->srvname, str);
//          }
//      }

  }

  close (sockfd);

  return 0;
}
Exemplo n.º 17
0
static SOCKET server_connect(const char *host, unsigned short nport)
{
#ifdef USE_GETADDRINFO
	struct addrinfo *addr;
	char port[6];
#else
	struct hostent *he;
	char **ap;
#endif

#ifdef WIN32
	static int need_init = 1;
	if (need_init) {
		WSADATA wsa;
		if (WSAStartup(MAKEWORD(2, 0), &wsa))
			return INVALID_SOCKET;
		need_init = 0;
	}
#elif defined(USE_AMITCP)
	if (!socket_base) {
		socket_base = OpenLibrary("bsdsocket.library", 4);
		if (!socket_base)
			return INVALID_SOCKET;
	}
#endif

#ifdef USE_GETADDRINFO

	snprintf(port, sizeof(port), "%u", nport);
	if (getaddrinfo(host, port, 0, &addr) != 0)
		return INVALID_SOCKET;

	for (; addr; addr = addr->ai_next) {
		SOCKET sock;
		int family = addr->ai_family;
		struct sockaddr *sa = addr->ai_addr;
		int sa_len = (int) addr->ai_addrlen; /* elim. warning on (at least) Win/x64, size_t vs. int/socklen_t */

#else

	he = gethostbyname(host);
	if (!he)
		return INVALID_SOCKET;

	for (ap = he->h_addr_list; *ap; ++ap) {
		SOCKET sock;
		int family = he->h_addrtype;
		struct sockaddr_in sin;
		struct sockaddr *sa = (struct sockaddr *)&sin;
		int sa_len = sizeof(*sa);

		sin.sin_family = he->h_addrtype;
		sin.sin_port = htons(nport);
		memcpy(&sin.sin_addr, *ap, he->h_length);
		memset(&sin.sin_zero, 0, sizeof(sin.sin_zero));

#endif

		sock = socket(family, SOCK_STREAM, 0);
		if (sock == INVALID_SOCKET)
			continue;

		if (connect(sock, sa, sa_len) >= 0) {
			char greet[128];

			if (xsend(sock, CLIENT_GREET, strlen(CLIENT_GREET), 0) ||
				xrecv(sock, greet, strlen(SERVER_GREET), 0)) {
				closesocket(sock);
				continue;
			}

			if (!strncmp(SERVER_GREET, greet, strlen(SERVER_GREET)))
				return sock;
		}

		closesocket(sock);
	}

	return INVALID_SOCKET;
}

#else

void sync_set_io_cb(struct sync_device *d, struct sync_io_cb *cb)
{
	d->io_cb.open = cb->open;
	d->io_cb.read = cb->read;
	d->io_cb.close = cb->close;
}
Exemplo n.º 18
0
int zmq::socket_base_t::recv (::zmq_msg_t *msg_, int flags_)
{
    if (unlikely (ctx_terminated)) {
        errno = ETERM;
        return -1;
    }

    //  Get the message.
    int rc = xrecv (msg_, flags_);
    int err = errno;

    //  Once every inbound_poll_rate messages check for signals and process
    //  incoming commands. This happens only if we are not polling altogether
    //  because there are messages available all the time. If poll occurs,
    //  ticks is set to zero and thus we avoid this code.
    //
    //  Note that 'recv' uses different command throttling algorithm (the one
    //  described above) from the one used by 'send'. This is because counting
    //  ticks is more efficient than doing RDTSC all the time.
    if (++ticks == inbound_poll_rate) {
        if (unlikely (process_commands (false, false) != 0))
            return -1;
        ticks = 0;
    }

    //  If we have the message, return immediately.
    if (rc == 0) {
        rcvmore = msg_->flags & ZMQ_MSG_MORE;
        if (rcvmore)
            msg_->flags &= ~ZMQ_MSG_MORE;
        return 0;
    }

    //  If we don't have the message, restore the original cause of the problem.
    errno = err;

    //  If the message cannot be fetched immediately, there are two scenarios.
    //  For non-blocking recv, commands are processed in case there's an
    //  activate_reader command already waiting int a command pipe.
    //  If it's not, return EAGAIN.
    if (flags_ & ZMQ_NOBLOCK) {
        if (errno != EAGAIN)
            return -1;
        if (unlikely (process_commands (false, false) != 0))
            return -1;
        ticks = 0;

        rc = xrecv (msg_, flags_);
        if (rc == 0) {
            rcvmore = msg_->flags & ZMQ_MSG_MORE;
            if (rcvmore)
                msg_->flags &= ~ZMQ_MSG_MORE;
        }
        return rc;
    }

    //  In blocking scenario, commands are processed over and over again until
    //  we are able to fetch a message.
    bool block = (ticks != 0);
    while (rc != 0) {
        if (errno != EAGAIN)
            return -1;
        if (unlikely (process_commands (block, false) != 0))
            return -1;
        rc = xrecv (msg_, flags_);
        ticks = 0;
        block = true;
    }

    rcvmore = msg_->flags & ZMQ_MSG_MORE;
    if (rcvmore)
        msg_->flags &= ~ZMQ_MSG_MORE;
    return 0;
}
int zmq::socket_base_t::recv (msg_t *msg_, int flags_)
{
    //  Check whether the library haven't been shut down yet.
    if (unlikely (ctx_terminated)) {
        errno = ETERM;
        return -1;
    }

    //  Check whether message passed to the function is valid.
    if (unlikely (!msg_ || !msg_->check ())) {
        errno = EFAULT;
        return -1;
    }

    //  Once every inbound_poll_rate messages check for signals and process
    //  incoming commands. This happens only if we are not polling altogether
    //  because there are messages available all the time. If poll occurs,
    //  ticks is set to zero and thus we avoid this code.
    //
    //  Note that 'recv' uses different command throttling algorithm (the one
    //  described above) from the one used by 'send'. This is because counting
    //  ticks is more efficient than doing RDTSC all the time.
    if (++ticks == inbound_poll_rate) {
        if (unlikely (process_commands (0, false) != 0))
            return -1;
        ticks = 0;
    }

    //  Get the message.
    int rc = xrecv (msg_);
    if (unlikely (rc != 0 && errno != EAGAIN))
        return -1;

    //  If we have the message, return immediately.
    if (rc == 0) {
        if (file_desc != retired_fd)
            msg_->set_fd(file_desc);
        extract_flags (msg_);
        return 0;
    }

    //  If the message cannot be fetched immediately, there are two scenarios.
    //  For non-blocking recv, commands are processed in case there's an
    //  activate_reader command already waiting int a command pipe.
    //  If it's not, return EAGAIN.
    if (flags_ & ZMQ_DONTWAIT || options.rcvtimeo == 0) {
        if (unlikely (process_commands (0, false) != 0))
            return -1;
        ticks = 0;

        rc = xrecv (msg_);
        if (rc < 0)
            return rc;
        if (file_desc != retired_fd)
            msg_->set_fd(file_desc);
        extract_flags (msg_);
        return 0;
    }

    //  Compute the time when the timeout should occur.
    //  If the timeout is infinite, don't care.
    int timeout = options.rcvtimeo;
    uint64_t end = timeout < 0 ? 0 : (clock.now_ms () + timeout);

    //  In blocking scenario, commands are processed over and over again until
    //  we are able to fetch a message.
    bool block = (ticks != 0);
    while (true) {
        if (unlikely (process_commands (block ? timeout : 0, false) != 0))
            return -1;
        rc = xrecv (msg_);
        if (rc == 0) {
            ticks = 0;
            break;
        }
        if (unlikely (errno != EAGAIN))
            return -1;
        block = true;
        if (timeout > 0) {
            timeout = (int) (end - clock.now_ms ());
            if (timeout <= 0) {
                errno = EAGAIN;
                return -1;
            }
        }
    }

    if (file_desc != retired_fd)
        msg_->set_fd(file_desc);
    extract_flags (msg_);
    return 0;
}