예제 #1
0
파일: evcom.c 프로젝트: bernd/node
enum evcom_stream_state
evcom_stream_state (evcom_stream *stream)
{
  if (stream->recvfd < 0 && stream->sendfd && stream->flags == 0) {
    return EVCOM_INITIALIZED;
  }

  if (stream->recvfd < 0 && stream->sendfd < 0) return EVCOM_CLOSED;

  if (!CONNECTED(stream)) return EVCOM_CONNECTING;

  if (GOT_CLOSE(stream)) {
    if (READABLE(stream)) {
      return EVCOM_CONNECTED_RO;
    } else {
      return EVCOM_CLOSING;
    }
  }

  if (READABLE(stream) && WRITABLE(stream)) return EVCOM_CONNECTED_RW;

  if (WRITABLE(stream)) return EVCOM_CONNECTED_WO;

  if (READABLE(stream)) return EVCOM_CONNECTED_RO;

  return EVCOM_CLOSING;
}
예제 #2
0
string
kpse_readable_file P1C(const_string, name)
{
  string ret;

#ifdef WIN32
  unsigned int st = 0;
#else /* ! WIN32 */
  struct stat st;
#endif

  kpse_normalize_path((string)name);
  if (READABLE (name, st)) {
      ret = (string) name;
#ifdef ENAMETOOLONG
  } else if (errno == ENAMETOOLONG) {
      ret = kpse_truncate_filename (name);

      /* Perhaps some other error will occur with the truncated name, so
         let's call access again.  */
      if (!READABLE (ret, st)) { /* Failed.  */
          if (ret != name) free (ret);
          ret = NULL;
      }
#endif /* ENAMETOOLONG */
  } else { /* Some other error.  */
      if (errno == EACCES) { /* Maybe warn them if permissions are bad.  */
          if (!kpse_tex_hush ("readable")) {
              perror (name);
          }
      }
      ret = NULL;
  }
  return ret;
}
예제 #3
0
파일: evcom.c 프로젝트: bernd/node
static int
stream_send__wait_for_eof (evcom_stream *stream)
{
  if (READABLE(stream)) {
    ev_io_stop(D_LOOP_(stream) &stream->write_watcher);
    assert(stream->send_action == stream_send__wait_for_eof);
    return AGAIN;
  }

  stream->send_action = stream_send__close_one;
  return OKAY;
}
예제 #4
0
파일: evcom.c 프로젝트: bernd/node
static int
stream_recv__wait_for_close (evcom_stream *stream)
{
  assert(!READABLE(stream));

  if (!WRITABLE(stream)) {
    stream->recv_action = stream_recv__close;
    return OKAY;
  }

  ev_io_stop(D_LOOP_(stream) &stream->read_watcher);
  return AGAIN;
}
예제 #5
0
파일: evcom.c 프로젝트: bernd/node
void
evcom_stream_read_resume (evcom_stream *stream)
{
  stream->flags &= ~EVCOM_PAUSED;
  ev_timer_again(D_LOOP_(stream) &stream->timeout_watcher);
  if (stream->recv_action == stream_recv__wait_for_resume) {
    stream->recv_action = stream_recv__data;
  }
  if (ATTACHED(stream)) {
    ev_timer_again(D_LOOP_(stream) &stream->timeout_watcher);
    if (READABLE(stream)) ev_io_start(D_LOOP_(stream) &stream->read_watcher);
  }
}
예제 #6
0
파일: evcom.c 프로젝트: bernd/node
void
evcom_stream_attach (EV_P_ evcom_stream *stream)
{
  D_LOOP_SET(stream, EV_A);
  stream->flags |= EVCOM_ATTACHED;

  ev_timer_again(EV_A_ &stream->timeout_watcher);

  if (READABLE(stream)) {
    ev_io_start(EV_A_ &stream->read_watcher);
  }

  if (WRITABLE(stream)) {
    ev_io_start(EV_A_ &stream->write_watcher);
  }
}
/*-------------------------------------------
| Name:ungetc
| Description:
| Parameters:
| Return Type:
| Comments:
| See:
---------------------------------------------*/
int __ungetc(int c, FILE *fp) {
   unsigned char *p;

   __thr_safe_lock(fp);
   //__init_stdio();

   /* If can't read or there's been an error, or c == EOF, or ungot slot
    * already filled, then return EOF */
   /*
    * This can only happen if an fgetc triggered a read (that filled
    * the buffer for case 2 above) and then we ungetc 3 chars.
    */
   if (!READABLE(fp) || (fp->mode & (__MODE_UNGOT | __MODE_ERR))
       || (c == EOF) ) {
      __thr_safe_unlock(fp);
      return EOF;
   }

   if (WRITING(fp)) {         /* Commit any write-buffered chars. */
      fflush(fp);
   }

   if (fp->bufpos > fp->bufstart) { /* We have space before bufpos. */
      p = --fp->bufpos;
   } else if (fp->bufread == fp->bufpos) { /* Buffer is empty. */
      p = fp->bufread++;
   } else {
      fp->mode |= __MODE_UNGOT;
      __thr_safe_unlock(fp);
      //p = &(fp->ungot);
      return EOF;
   }
   fp->mode &= ~(__MODE_EOF); /* Clear EOF indicator. */

   if (*p != (unsigned char) c) { /* Don't store if same, because could */
      *p = (unsigned char) c; /* be sscanf from a const string!!! */
   }

   __thr_safe_unlock(fp);
   return c;
}
예제 #8
0
파일: evcom.c 프로젝트: bernd/node
static int
stream_recv__data (evcom_stream *stream)
{
  char buf[EVCOM_CHUNKSIZE];
  size_t buf_size = EVCOM_CHUNKSIZE;
  ssize_t recved;

  while (READABLE(stream)) {
    assert(CONNECTED(stream));

    if (PAUSED(stream)) {
      stream->recv_action = stream_recv__wait_for_resume;
      return OKAY;
    }


#if EVCOM_HAVE_GNUTLS
    if (SECURE(stream)) {
      recved = gnutls_record_recv(stream->session, buf, buf_size);

      if (gnutls_error_is_fatal(recved)) {
        stream->gnutls_errorno = recved;
        stream->recv_action = stream_recv__close;
        return OKAY;
      }

      if (recved == GNUTLS_E_INTERRUPTED || recved == GNUTLS_E_AGAIN) {
        if (1 == gnutls_record_get_direction((stream)->session)) {
          fprintf(stderr, "(evcom) gnutls recv: unexpected switch direction!\n");
          ev_io_stop(D_LOOP_(stream) &(stream)->read_watcher); 
          ev_io_start(D_LOOP_(stream) &(stream)->write_watcher);
        }
        return AGAIN;
      }

      /* A server may also receive GNUTLS_E_REHANDSHAKE when a client has
       * initiated a andshake. In that case the server can only initiate a
       * handshake or terminate the connection. */
      if (recved == GNUTLS_E_REHANDSHAKE) {
        assert(WRITABLE(stream));
        stream->recv_action = stream__handshake;
        stream->send_action = stream__handshake;
        return OKAY;
      }
    } else 
#endif /* EVCOM_HAVE_GNUTLS */
    {
      recved = read(stream->recvfd, buf, buf_size);
    }

    if (recved < 0) {
      if (errno == EAGAIN || errno == EINTR) {
        assert(stream->recv_action == stream_recv__data);
        return AGAIN;
      } 
      
      if (errno != ECONNRESET) {
        evcom_perror("recv()", stream->errorno);
      }

      stream->errorno = errno;
      stream->recv_action = stream_recv__close;
      return OKAY;
    }

    ev_timer_again(D_LOOP_(stream) &stream->timeout_watcher);

    assert(recved >= 0);

    if (recved == 0) {
      stream->flags &= ~EVCOM_READABLE;
      ev_io_stop(D_LOOP_(stream) &stream->read_watcher);
      stream->recv_action = stream_recv__wait_for_close;
    }

    /* NOTE: EOF is signaled with recved == 0 on callback */
    if (stream->on_read) stream->on_read(stream, buf, recved);

    if (recved == 0) {
      return OKAY;
    }
  }
  return AGAIN;
}