예제 #1
0
int
mu_streamref_create_abridged (mu_stream_t *pref, mu_stream_t str,
			      mu_off_t start, mu_off_t end)
{
  int rc;
  mu_off_t off;
  int flags;
  struct _mu_streamref *sp;
  
  rc = mu_stream_seek (str, 0, MU_SEEK_SET, &off);/*FIXME: SEEK_CUR?*/
  if (rc)
    return rc;
  mu_stream_get_flags (str, &flags);
  sp = (struct _mu_streamref *)
         _mu_stream_create (sizeof (*sp), flags | _MU_STR_OPEN);
  if (!sp)
    return ENOMEM;

  mu_stream_ref (str);

  sp->stream.read = _streamref_read; 
  if (str->readdelim)
    sp->stream.readdelim = _streamref_readdelim; 
  sp->stream.write = _streamref_write;
  sp->stream.flush = _streamref_flush;
  sp->stream.open = _streamref_open; 
  sp->stream.close = _streamref_close;
  sp->stream.done = _streamref_done; 
  sp->stream.seek = _streamref_seek; 
  sp->stream.size = _streamref_size; 
  sp->stream.ctl = _streamref_ctl;
  sp->stream.wait = _streamref_wait;
  sp->stream.truncate = _streamref_truncate;
  sp->stream.shutdown = _streamref_shutdown;
  sp->stream.error_string = _streamref_error_string;

  sp->transport = str;
  sp->start = start;
  sp->end = end;
  if (off < start || off > end)
    off = start;
  sp->offset = off;
  *pref = (mu_stream_t) sp;

  mu_stream_set_buffer (*pref, mu_buffer_full, 0);

  return 0;
}
예제 #2
0
static int
_tcp_open (mu_stream_t stream)
{
  struct _tcp_instance *tcp = (struct _tcp_instance *)stream;
  int flgs, ret;
  socklen_t namelen;
  struct sockaddr_in peer_addr;
  int flags;

  mu_stream_get_flags (stream, &flags);

  switch (tcp->state)
    {
    case TCP_STATE_INIT:
      if (tcp->fd == -1)
	{
	  tcp->fd = socket (tcp->remote_addr->addr->sa_family, SOCK_STREAM, 0);
	  if (tcp->fd == -1)
	    return errno;
	}
      if (flags & MU_STREAM_NONBLOCK)
	{
	  flgs = fcntl (tcp->fd, F_GETFL);
	  flgs |= O_NONBLOCK;
	  fcntl (tcp->fd, F_SETFL, flgs);
	  mu_stream_set_flags (stream, MU_STREAM_NONBLOCK);
	}
      if (tcp->source_addr)
	{
	  if (bind (tcp->fd, tcp->source_addr->addr,
		    tcp->source_addr->addrlen) < 0)
	    {
	      int e = errno;
	      close (tcp->fd);
	      tcp->fd = -1;
	      return e;
	    }
	}
      
      tcp->state = TCP_STATE_RESOLVING;
      
    case TCP_STATE_RESOLVING:
      tcp->state = TCP_STATE_RESOLVE;
      
    case TCP_STATE_RESOLVE:
      if (connect (tcp->fd, tcp->remote_addr->addr,
		   tcp->remote_addr->addrlen) == -1)
	{
	  ret = errno;
	  if (ret == EINPROGRESS || ret == EAGAIN)
	    {
	      tcp->state = TCP_STATE_CONNECTING;
	      ret = EAGAIN;
	    }
	  else
	    _tcp_close (stream);
	  return ret;
	}
      tcp->state = TCP_STATE_CONNECTING;
      
    case TCP_STATE_CONNECTING:
      namelen = sizeof (peer_addr);
      if (getpeername (tcp->fd,
		       (struct sockaddr *) &peer_addr, &namelen) == 0)
	tcp->state = TCP_STATE_CONNECTED;
      else
	{
	  ret = errno;
	  _tcp_close (stream);
	  return ret;
	}
      break;
    }
  return 0;
}