Changeset - 1c075fe042df
[Not reviewed]
default
0 2 0
Nathan Brink (binki) - 15 years ago 2010-07-18 20:54:37
ohnobinki@ohnopublishing.net
Fixed one of the stupidest mistakes one could make when using poll(); I used .events where I needed .revents.
Fixed typo in function name: mulitiio_poll_invoke_handlers() -> multiio_poll_invoke_handlers() and small variable initialization cleanup.
2 files changed with 4 insertions and 4 deletions:
0 comments (0 inline, 0 general)
src/common/multiio.c
Show inline comments
 
@@ -64,225 +64,225 @@ struct multiio_context
 
  /* the number of socket types registered (equivilent to the type ID of the next registered type) */
 
  multiio_socket_type_t num_socket_types;
 
  /* the information about each individual socket type keyed by the type ID */
 
  struct multiio_socket_type_info *socket_types;
 
};
 

	
 
/*
 
  stores information about a handler associated with a socket type/class.
 
 */
 
struct multiio_socket_type_handler_info
 
{
 
  /* the poll() event to which this handler responds */
 
  short event;
 
  /* the handler function to call when the event is matched */
 
  multiio_event_handler_func_t handler;
 
  /* the pointer passed to multiio_event_handler_register() */
 
  void *handler_data;
 
};
 

	
 
/**
 
   Finds the index in the context->pollfds array of a particular socket.
 

	
 
   @param context the multiio context
 
   @param fd the socket to search for
 
   @param index a pointer which will be filled with the index of the socket if found
 
   @return 0 if the pollfds entry is found, 1 if the entry is not found
 
 */
 
int multiio_pollfd_index_by_fd(const multiio_context_t context, int fd, size_t *index);
 

	
 
multiio_context_t multiio_context_new()
 
{
 
  struct multiio_context *context;
 

	
 
  context = malloc(sizeof(struct multiio_context));
 
  if(!context)
 
    return NULL;
 

	
 
  context->pollfds = malloc(sizeof(struct pollfd) * 2);
 
  if(!context->pollfds)
 
    {
 
      free(context);
 
      return NULL;
 
    }
 
  context->pollfds_len = 2;
 
  context->nfds = 0;
 
  context->socket_infos = malloc(sizeof(struct multiio_socket_info) * 2);
 

	
 
  context->num_socket_types = 0;
 
  context->socket_types = NULL;
 

	
 
  if(!context->pollfds
 
     || !context->socket_infos)
 
    {
 
      free(context->pollfds);
 
      free(context->socket_infos);
 
      free(context);
 

	
 
      return NULL;
 
    }
 

	
 
  return context;
 
}
 

	
 
int multiio_context_free(multiio_context_t context)
 
{
 
  size_t counter;
 
  /*
 
    clean up pollfds and socket_infos
 
   */
 
  free(context->pollfds);
 
  free(context->socket_infos);
 

	
 
  /*
 
    wipe up the socket_types
 
   */
 
  for(counter = 0; counter < context->num_socket_types; counter ++)
 
    list_free(context->socket_types[counter].type_handlers, LIST_DEALLOC);
 
  free(context->socket_types);
 

	
 
  /*
 
    bye!
 
   */
 
  free(context);
 

	
 
  return 0;
 
}
 

	
 
struct multiio_poll_travinfo
 
{
 
  multiio_context_t multiio;
 
  struct multiio_socket_info *socket_info;
 
  struct pollfd *pollfd;
 
};
 
/**
 
   list traverser for multiio_poll()
 
 */
 
int mulitiio_poll_invoke_handlers(struct multiio_poll_travinfo *travinfo, struct multiio_socket_type_handler_info *handler_info)
 
int multiio_poll_invoke_handlers(struct multiio_poll_travinfo *travinfo, struct multiio_socket_type_handler_info *handler_info)
 
{
 
  short event;
 

	
 
  event = travinfo->pollfd->events & handler_info->event;
 
  event = travinfo->pollfd->revents & handler_info->event;
 
  if(!event)
 
    return TRUE;
 

	
 
  handler_info->handler(travinfo->multiio,
 
			travinfo->pollfd->fd,
 
			event,
 
			handler_info->handler_data,
 
			travinfo->socket_info->socket_data);
 

	
 
  return TRUE;
 
}
 

	
 
int multiio_poll(multiio_context_t context)
 
{
 
  size_t counter;
 
  struct multiio_poll_travinfo travinfo;
 

	
 
  poll(context->pollfds, context->nfds, -1);
 

	
 
  for(counter = 0; counter < context->nfds; counter ++)
 
    if(context->pollfds[counter].revents)
 
      {
 
	travinfo.multiio = context;
 
	travinfo.socket_info = &context->socket_infos[counter];
 
	travinfo.pollfd = &context->pollfds[counter];
 
	list_traverse(context->socket_types[context->socket_infos[counter].socket_type].type_handlers,
 
		      &travinfo,
 
		      (list_traverse_func_t)&mulitiio_poll_invoke_handlers,
 
		      (list_traverse_func_t)&multiio_poll_invoke_handlers,
 
		      LIST_FRNT | LIST_SAVE);
 
      }
 

	
 
  return 0;
 
}
 

	
 
int multiio_socket_type_register(multiio_context_t context, multiio_socket_type_t *new_type)
 
{
 
  struct multiio_socket_type_info *new_socket_types;
 

	
 
  new_socket_types = malloc(sizeof(struct multiio_socket_type_info) * (context->num_socket_types + 1));
 
  if(!new_socket_types)
 
    return 1;
 

	
 
  *new_type = context->num_socket_types;
 
  new_socket_types[*new_type].type_handlers = list_init();
 
  if(!new_socket_types[*new_type].type_handlers)
 
    {
 
      free(new_socket_types);
 
      return 2;
 
    }
 

	
 

	
 
  if(context->num_socket_types)
 
    {
 
      memcpy(new_socket_types, context->socket_types, sizeof(struct multiio_socket_type_info) * context->num_socket_types);
 
      free(context->socket_types);
 
    }
 

	
 
  context->socket_types = new_socket_types;
 
  context->num_socket_types ++;
 

	
 
  return 0;
 
}
 

	
 
int multiio_event_handler_register(multiio_context_t context, multiio_socket_type_t socket_type, short event, multiio_event_handler_func_t handler_func, void *handler_data)
 
{
 
  struct multiio_socket_type_handler_info handler_info;
 

	
 
  if(socket_type >= context->num_socket_types)
 
    return 1;
 

	
 
  if(!event)
 
    return 2;
 

	
 
  handler_info.event = event;
 
  handler_info.handler = handler_func;
 
  handler_info.handler_data = handler_data;
 

	
 
  list_insert_after(context->socket_types[socket_type].type_handlers, &handler_info, sizeof(struct multiio_socket_type_handler_info));
 

	
 
  return 0;
 
}
 

	
 
int multiio_socket_add(multiio_context_t context, int fd, multiio_socket_type_t socket_type, void *socket_data, short events)
 
{
 
  struct pollfd *pollfds;
 
  struct multiio_socket_info *socket_infos;
 
  size_t new_pollfds_len;
 

	
 
  int fdstatus;
 
  int tmp;
 

	
 
  fdstatus = fcntl(fd, F_GETFL);
 
  fdstatus |= O_NONBLOCK;
 
  tmp = fcntl(fd, F_SETFL, fdstatus);
 
  if(tmp == -1)
 
    {
 
      perror("fcntl");
 
      return 1;
 
    }
 

	
 
  if(socket_type >= context->num_socket_types)
 
    return 1;
 

	
 
  /**
 
     extend sockfds array
 
   */
 
  if(context->nfds >= context->pollfds_len)
 
    {
 
      new_pollfds_len = (context->pollfds_len + 1) * 2;
 

	
 
      pollfds = malloc(sizeof(struct pollfd) * new_pollfds_len);
 
      socket_infos = malloc(sizeof(struct multiio_socket_info) * new_pollfds_len);
 

	
 
      if(!pollfds
 
	 || !socket_infos)
 
	return 1;
 

	
 
      memcpy(pollfds, context->pollfds, sizeof(struct pollfd) * context->pollfds_len);
 
      memcpy(socket_infos, context->socket_infos, sizeof(struct multiio_socket_info) * context->pollfds_len);
 

	
 
      free(context->pollfds);
 
      free(context->socket_infos);
 

	
 
      context->pollfds = pollfds;
src/common/remoteio.c
Show inline comments
 
@@ -555,206 +555,206 @@ int _remoteio_ssh_open(struct remoteio *
 
  if(server->username)
 
    _distren_asprintf(&userhost, "%s@%s", server->username, server->hostname);
 
  else
 
    userhost = strdup(server->hostname);
 
  sshargs[1] = userhost;
 

	
 
  rtn = execio_open( &rem->execio, "ssh", sshargs);
 
  if(rtn)
 
    {
 
      fprintf(stderr, "error opening remoteio channel to ssh userhost ``%s''\n" , userhost);
 
      free(userhost);
 
      return 1;
 
    }
 
  free(userhost);
 
  
 
  return 0;
 
}
 

	
 
int _remoteio_ssh_read(struct remoteio *rem, void *buf, size_t len, size_t *bytesread)
 
{
 
  return execio_read(rem->execio, buf, len, bytesread);
 
}
 

	
 
int _remoteio_ssh_write(struct remoteio *rem, void *buf, size_t len, size_t *byteswritten)
 
{
 
  return execio_write(rem->execio, buf, len, byteswritten);
 
}
 

	
 
int _remoteio_ssh_close(struct remoteio *rem)
 
{
 
  int rtn;
 
  
 
  rtn = execio_close(rem->execio);
 
  if(rtn)
 
    fprintf(stderr, "%s:%d: error closing execio\n", __FILE__, __LINE__);
 
  
 
  return rtn;
 
}
 

	
 
#ifndef _WIN32
 
/*
 
  local sockets implementation (``named pipes''), unix-only
 
 */
 
int _remoteio_sock_open(struct remoteio *rem, struct remoteio_server *server)
 
{
 
  int sock;
 
  struct sockaddr_un sockaddr;
 

	
 
  /*
 
    The POSIX docs pretty much say that I can't depend on sockpath being able to be longer than 
 
    some proprietary length. So, if the compiler specifies a long path for RUNSTATEDIR, it could
 
    cause a buffer overflow.
 
   */
 
  char *sockpath = RUNSTATEDIR "/distrend.sock";
 
  unsigned int sockaddr_len;
 

	
 
  sock = socket(AF_UNIX, SOCK_STREAM, 0);
 
  if(sock == -1)
 
    {
 
      perror("socket");
 
      return 1;
 
    }
 

	
 
  sockaddr.sun_family = AF_UNIX;
 
  /*
 
    The terminating NULL should not be included in what's copied to sun_path,
 
    although it won't hurt as long as strlen(sockpath) < max socket length
 
   */
 
  for(sockaddr_len = 0; sockpath[sockaddr_len]; sockaddr_len ++)
 
    sockaddr.sun_path[sockaddr_len] = sockpath[sockaddr_len];
 

	
 
  if(connect(sock, (struct sockaddr *)&sockaddr, sockaddr_len) == -1)
 
    {
 
      perror("connect");
 
      close(sock);
 
      return 1;
 
    }
 

	
 
  rem->sock = sock;
 

	
 
  return 0;
 
}
 

	
 
#endif /* _WIN32 */
 

	
 
int _remoteio_sock_close(struct remoteio *rem)
 
{
 
  close(rem->sock);
 

	
 
  return 0;
 
}
 

	
 
int _remoteio_sock_read(struct remoteio *rem, void *buf, size_t len, size_t *bytesread)
 
{
 
  ssize_t readrtn;
 

	
 
  *bytesread = 0;
 
  readrtn = read(rem->sock, buf, len);
 
  /*
 
    The following is valid for blocking sockets:
 
   */
 
  if(readrtn == -1)
 
    {
 
      /*
 
	in this case, we may have been interrupted by a signal and errno == EINTR
 
	or the connection was reset and errno = ECONNRESET
 

	
 
	Some of these are not error conditions:
 
       */
 
      perror("read");
 
      *bytesread = 0;
 

	
 
      if(errno != EINTR)
 
	{
 
	  fprintf(stderr, "error reading socket in remoteio_sock_read\n");
 
	  return 1;
 
	}
 

	
 
      return 0;
 
    }
 

	
 
  *bytesread = readrtn;
 
  if(!readrtn)
 
    {
 
      /*
 
	means EOF except when FD is in ``message-nondiscard'' or ``message-discard''
 
	modes.
 
       */
 
      return 1;
 
    }
 

	
 
  return 0;
 
}
 

	
 
int _remoteio_sock_write(struct remoteio *rem, void *buf, size_t len, size_t *byteswritten)
 
{
 
  ssize_t writertn;
 

	
 
  writertn = write(rem->sock, buf, len);
 

	
 
  if(writertn == -1)
 
    {
 
      perror("write");
 
      if(errno != EINTR)
 
	{
 
	  fprintf(stderr, "error writing to socket in remoteio_sock_write()\n");
 
	  return 1;
 
	}
 
    }
 

	
 
  *byteswritten = writertn;
 
  if(!writertn)
 
    {
 
      /*
 
	should we consider this an error? I'm pretty
 
	sure we should :-/
 
       */
 
      fprintf(stderr, "write() returned 0 in remoteio_sock_write()\n");
 
      return 1;
 
    }
 

	
 
  return 0;
 
}
 

	
 
/**
 
   TCP, taking advantage of the two generic socks read/write functions:
 
 */
 
int _remoteio_tcp_open(struct remoteio *rem, struct remoteio_server *server)
 
{
 
  int tmp;
 
  int tmp2;
 

	
 
  int sock;
 

	
 
  char *hostname;
 
  char *port;
 

	
 
  struct addrinfo addrinfo_hints;
 
  struct addrinfo *addrinfo_res;
 

	
 
  /**
 
     only hostname should be free()-ed, not port,
 
     because both are from the same block of malloc()-ed
 
     memory
 
   */
 
  hostname = strdup(server->hostname);
 
  for(port = hostname;
 
      *port && *port != ':';
 
      port ++)
 
    ;
 
  if(*port)
 
    {
 
      *port = '\0';
 
      port ++;
 
    }
 
  else
 
    port = REMOTEIO_DEFAULT_PORT;
 

	
 
  memset(&addrinfo_hints, '\0', sizeof(struct addrinfo));
 
  addrinfo_hints.ai_family = AF_UNSPEC;
 
#ifdef _WIN32
 
  /* windows lacks stuff documented in POSIX, I guess :-( */
 
  addrinfo_hints.ai_flags = 0;
 
#else
 
  addrinfo_hints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG;
 
#endif
 
  addrinfo_hints.ai_socktype = SOCK_STREAM;
0 comments (0 inline, 0 general)