Changeset - 00afcd810c9b
[Not reviewed]
Merge default
0 5 0
Nathan Brink (binki) - 15 years ago 2010-07-29 21:28:47
ohnobinki@ohnopublishing.net
merge
5 files changed with 22 insertions and 13 deletions:
0 comments (0 inline, 0 general)
src/common/execio.c
Show inline comments
 
@@ -156,25 +156,25 @@ int _execio_checkpid(struct execio *eio)
 
  
 
#ifdef _WIN32
 
  waitpid(eio->child, &childstatus, 0);
 
#else
 
  waitpid(eio->child, &childstatus, WNOHANG);
 
#endif
 
  /* perror()? */
 

	
 
  return WIFEXITED(childstatus);
 
}
 

	
 

	
 
int execio_read(struct execio *eio, void *buf, size_t len, size_t *bytesread)
 
int execio_read(struct execio *eio, const void *buf, size_t len, size_t *bytesread)
 
{
 
  ssize_t ret;
 
  /*
 
    TODO: detect NULL eio? 
 
    TODO: errno?
 
    update status of eio for execio_status/to be able to cleanup subproc??
 

	
 
    whenever read() returns 0, it means EOF
 
   */
 
  
 
  ret = read(eio->pipe_read, buf, len);
 
  if(ret == -1)
 
@@ -194,25 +194,25 @@ int execio_read(struct execio *eio, void
 

	
 
  (*bytesread) = (size_t)ret;
 
  if(!ret)
 
    {
 
      /* should also be able to figure out if is bad fd and should set EXECIO_STATE_ERROR instead of _EOF */
 
      eio->state = EXECIO_STATE_EOF;
 
      return 1;
 
    }
 

	
 
  return 0;
 
}
 

	
 
int execio_write(struct execio *eio, void *buf, size_t len, size_t *bytesread)
 
int execio_write(struct execio *eio, const void *buf, size_t len, size_t *bytesread)
 
{
 
  errno = 0;
 
  (*bytesread) = write(eio->pipe_write, buf, len);
 
  if(!*bytesread)
 
    {
 
      switch(errno)
 
	{
 
	case EPIPE:
 
	  /* 
 
	     the program closed the pipe (died)
 
	  */
 
	fprintf(stderr, "execio_write: the child program closed its stdin pipe\n");
src/common/execio.h
Show inline comments
 
@@ -45,26 +45,26 @@ struct execio
 

	
 
/**
 
  runs progname with the arguments in argv. argv must be null terminated!!!!!!!!!
 

	
 
  returns nonzero return on error
 
*/
 
int execio_open(struct execio **eio, const char *progname, char *const argv[]);
 

	
 
/**
 
   doesn't block,
 
   returns 0 on success, 1 on failure
 
*/
 
int execio_read(struct execio *eio, void *buf, size_t len, size_t *bytesread);
 
int execio_write(struct execio *eio, void *buf, size_t len, size_t *byteswritten);
 
int execio_read(struct execio *eio, const void *buf, size_t len, size_t *bytesread);
 
int execio_write(struct execio *eio, const void *buf, size_t len, size_t *byteswritten);
 

	
 
/**
 
  use this function to determine if the using program should keep trying to read/write
 

	
 
  @todo is this function good enough/necessary?
 
 */
 
enum execio_state execio_state(struct execio *eio);
 

	
 
/**
 
   Closes an execio session.
 
   @return nonzero on error 
 
*/
src/common/libremoteio.h
Show inline comments
 
@@ -108,25 +108,25 @@ struct remoteio
 
   * remoteio_close() will act normal. If set to 1, then
 
   * remoteio_close() will not actually free this struct but instead
 
   * increment this variable to 2. This is so that read_handler can
 
   * call remoteio_close() without segfaulting us.
 
   */
 
  short careful_free;
 
};
 

	
 

	
 
/* lookup table */
 
typedef int remoteio_open_func_t(struct remoteio *rem, struct remoteio_server *server);
 
typedef int remoteio_read_func_t(struct remoteio *rem, void *buf, size_t len, size_t *bytesread);
 
typedef int remoteio_write_func_t(struct remoteio *rem, void *buf, size_t len, size_t *bytesread);
 
typedef int remoteio_write_func_t(struct remoteio *rem, const void *buf, size_t len, size_t *bytesread);
 
typedef int remoteio_close_func_t(struct remoteio *rem);
 

	
 
struct remoteio_method_funcmap
 
{
 
  enum remoteio_method method;
 

	
 
  remoteio_open_func_t *open_func;
 
  remoteio_read_func_t *read_func;
 
  remoteio_write_func_t *write_func;
 
  remoteio_close_func_t *close_func;
 

	
 
  char *name; /*< used for error messages */
src/common/remoteio.c
Show inline comments
 
@@ -56,36 +56,36 @@ int _remoteio_handle_write(multiio_conte
 
			   int fd,
 
			   short revent,
 
			   struct remoteio_opts *opts,
 
			   struct remoteio *rem);
 
int _remoteio_handle_read(multiio_context_t multiio,
 
			  int fd,
 
			  short revent,
 
			  struct remoteio_opts *opts,
 
			  struct remoteio *rem);
 

	
 
int _remoteio_ssh_open(struct remoteio *rem, struct remoteio_server *server);
 
int _remoteio_ssh_read(struct remoteio *rem, void *buf, size_t len, size_t *bytesread);
 
int _remoteio_ssh_write(struct remoteio *rem, void *buf, size_t len, size_t *byteswritten);
 
int _remoteio_ssh_write(struct remoteio *rem, const void *buf, size_t len, size_t *byteswritten);
 
int _remoteio_ssh_close(struct remoteio *rem);
 

	
 
/**
 
   ``named pipes''
 
 */
 
#ifndef _WIN32
 
int _remoteio_sock_open(struct remoteio *rem, struct remoteio_server *server);
 
int _remoteio_sock_close(struct remoteio *rem);
 
#endif
 
int _remoteio_sock_read(struct remoteio *rem, void *buf, size_t len, size_t *bytesread);
 
int _remoteio_sock_write(struct remoteio *rem, void *buf, size_t len, size_t *byteswritten);
 
int _remoteio_sock_write(struct remoteio *rem, const void *buf, size_t len, size_t *byteswritten);
 

	
 
/**
 
   These borrow from _remoteio_sock_read() and _remoteio_sock_write().
 
 */
 
int _remoteio_tcp_open(struct remoteio *rem, struct remoteio_server *server);
 
int _remoteio_tcp_close(struct remoteio *rem);
 

	
 
/**
 
  lookup table for different methods of remoteio:
 
  the enum remoteio_method is the index of the entry to use for that method. 
 
  Regardless, a NULL terminator is required because the configuration function
 
  searches through this table for the method specified in the config file.
 
@@ -352,42 +352,43 @@ int _remoteio_handle_read(multiio_contex
 

	
 
  memmove(rem->inbuf.data, rem->inbuf.data + readlen, rem->inbuf.len - readlen);
 
  rem->inbuf.len -= readlen;
 

	
 
  return 0;
 
}
 

	
 

	
 
int remoteio_write(struct remoteio *rem, const void *buf, size_t len)
 
{
 
  struct remoteio_packet *packet;
 
  struct pollfd pollfd;
 
  ssize_t bytes_written;
 
  size_t bytes_written;
 
  int err;
 

	
 
  /**
 
   * This is probably about the only optimization that exists in
 
   * distren.... :-D
 
   *
 
   * Write to the client immediately if there are no other messages
 
   * waiting and if the client will accept it.
 
   */
 
  if(q_empty(rem->outmsgs))
 
    {
 
      pollfd.fd = rem->sock;
 
      pollfd.revents = POLLOUT;
 
      pollfd.events = 0;
 
      poll(&pollfd, 1, 0);
 
      if(pollfd.events & POLLOUT)
 
	{
 
	  bytes_written = write(rem->sock, buf, len);
 
	  err = funcmap[rem->method].write_func(rem, buf, len, &bytes_written);
 
	  if(bytes_written > 0)
 
	    {
 
	      len -= bytes_written;
 
	      buf += bytes_written;
 
	    }
 
	}
 
    }
 

	
 
  /**
 
   * zero length is easy... and might be possible if the above
 
   * optimization works ;-)
 
   */
 
@@ -535,26 +536,28 @@ struct remoteio_server *remoteio_getserv
 
  char *dispensible_servername;
 

	
 
  dispensible_servername = strdup(servername); /* for the sake of constness... */
 
  traversal_result = list_traverse(opts->servers, dispensible_servername, (list_traverse_func_t)&_remoteio_getserver_traverse, LIST_FRNT | LIST_ALTR);
 
  free(dispensible_servername);
 

	
 
  if(traversal_result == LIST_OK)
 
    return (struct remoteio_server *)list_curr(opts->servers);
 

	
 
  return (struct remoteio_server *)NULL;
 
}
 

	
 

	
 

	
 
size_t remoteio_sendq_len(const struct remoteio *rem)
 
{
 
  return (size_t)q_size(rem->outmsgs);
 
}
 

	
 
/**
 
   different remoteio methods' implementations:
 
 */
 

	
 
/*
 
  SSH, via execio
 
*/
 

	
 
int _remoteio_ssh_open(struct remoteio *rem, struct remoteio_server *server)
 
{
 
  char *userhost;
 
@@ -576,25 +579,25 @@ int _remoteio_ssh_open(struct remoteio *
 
      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)
 
int _remoteio_ssh_write(struct remoteio *rem, const 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__);
 
  
 
@@ -686,25 +689,25 @@ int _remoteio_sock_read(struct remoteio 
 
  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)
 
int _remoteio_sock_write(struct remoteio *rem, const 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;
src/common/remoteio.h
Show inline comments
 
@@ -120,13 +120,19 @@ int remoteio_open_socket(struct remoteio
 
int remoteio_write(struct remoteio *rem, const void *buf, size_t len);
 

	
 
/**
 
 * Closes a remoteio session.
 
 *
 
 * It is safe to call this function from within
 
 * remoteio_read_handle_func_t.
 
 *
 
 * @return nonzero on error
 
*/
 
int remoteio_close(struct remoteio *rem);
 

	
 
/**
 
 * Returns the number of unfulfilled remoteio_write() calls pending on
 
 * a remoteio handle.
 
 */
 
size_t remoteio_sendq_len(const struct remoteio *rem);
 

	
 
#endif
0 comments (0 inline, 0 general)