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; }
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; }
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; }
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; }
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); } }
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; }
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; }