if (w->session) {
nr = gnutls_record_recv(w->session, buf->data + buf->len, BUFSIZ);
- if (nr < 0 && gnutls_error_is_fatal(nr))
- return el_job_release(w, EL_RDHUP);
- if (nr <= 0) {
+ if (nr < 0 && !gnutls_error_is_fatal(nr)) {
int wr = gnutls_record_get_direction(w->session);
return el_job_setemode(w, wr ? EL_WRITING : EL_READING);
}
EL_JOB_CHECK(el_job_setemode(w, w->mode));
} else {
nr = read(w->fd, buf->data + buf->len, BUFSIZ);
- if (nr < 0) {
- if (errno == EINTR || errno == EAGAIN)
- return 0;
- }
- if (nr <= 0)
- return el_job_release(w, EL_RDHUP);
+ if (nr < 0 && (errno == EINTR || errno == EAGAIN))
+ return 0;
}
+ if (nr <= 0)
+ return el_job_release(w, EL_RDHUP);
buffer_extend(buf, nr);
return nr;
}
+ssize_t el_job_write(job_t *w, buffer_t *buf)
+{
+ ssize_t nr;
+
+ if (buf->len == 0)
+ return 0;
+
+ if (w->session) {
+ nr = gnutls_record_send(w->session, buf->data, buf->len);
+ if (nr < 0 && !gnutls_error_is_fatal(nr)) {
+ int wr = gnutls_record_get_direction(w->session);
+ return el_job_setemode(w, wr ? EL_WRITING : EL_READING);
+ }
+ EL_JOB_CHECK(el_job_setemode(w, w->mode));
+ } else {
+ nr = write(w->fd, buf->data, buf->len);
+ if (nr < 0 && (errno == EINTR || errno == EAGAIN))
+ return 0;
+ }
+ if (nr <= 0)
+ return el_job_release(w, EL_RDHUP);
+ buffer_splice(buf, 0, nr, NULL, 0);
+ return nr;
+}
+
int el_dispatch(int timeout)
{
struct epoll_event events[FD_SETSIZE];
__must_check__ int el_job_connect(job_t *w, struct sockaddr *, socklen_t len,
int type, int proto);
__must_check__ ssize_t el_job_read(job_t *w, buffer_t *buf);
+__must_check__ ssize_t el_job_write(job_t *w, buffer_t *buf);
static inline job_t *el_job_start(const machine_t *m, void *cfg) {
job_t *w = job_new();