static psckt_t * psckt_setup(psckt_t *sock, void *ctx, psckt_cb_t *callback) { sock->callback = callback; sock->ctx = ctx; sock->next = psckt_list; psckt_list = sock; if (callback) u_event_src(sock->fd, psckt_cb_manager, sock); return sock; }
/* ARGSUSED */ static void u_fd0_ready(void *c) { char *line = u_input_line; int n; /* before calling fgets, check to be sure that this process is * not in the background (via UNIX shell job control) */ if (u_in_background()) return; do { if (u_input_max < (line-u_input_line)+1024) { if (u_input_max > 16000) break; n = line - u_input_line; u_input_line = p_realloc(u_input_line, u_input_max+1024); u_input_max += 1024; line = u_input_line + n; } if (!fgets(line, 1024, stdin)) { int at_eof = feof(stdin); clearerr(stdin); if (++u_term_errs>3 || at_eof) { /* cannot read stdin -- maybe serious error, remove it */ u_event_src(0, (void (*)(void *))0, (void *)0); return; } } else { u_term_errs = 0; /* reset error counter on each successful read */ } n = strlen(line); line += n; } while (n==1023 && line[-1]!='\n'); if (line[-1]=='\n') line[-1] = '\0'; if (u_stdin) u_stdin(u_input_line); else p_stderr("\a"); /* beep to indicate rejection */ if (u_input_max>1024) { u_input_line = p_realloc(u_input_line, 1024); u_input_max = 1024; } }
static int psckt_shutdown(psckt_t *sock) { psckt_t *s, *prev; if (sock->fd != -1) { if (sock->callback) u_event_src(sock->fd, 0, sock); close(sock->fd); sock->fd = -1; } for (s=psckt_list,prev=0 ; s ; prev=s,s=s->next) if (s == sock) break; if (prev) prev->next = sock->next; else psckt_list = sock->next; if (sock->peer) { p_free(sock->peer); sock->peer = 0; } sock->callback = 0; sock->ctx = 0; return -1; /* convenience for send, recv */ }
/* return value <0 for error, <len means socket recv side closed */ long psckt_recv(psckt_t *sock, void *msg, long len) { char *cmsg = msg; int n; while (len > 0) { n = recv(sock->fd, cmsg, len, 0); if (n < 0) return (psckt_shutdown(sock), -1L); if (n == 0) { /* socket closed */ /* socket may close for recv but not for send, not full shutdown yet */ if (sock->callback) { /* ...but remove from event sources immediately */ sock->callback = 0; u_event_src(sock->fd, 0, sock); } break; } cmsg += n; len -= n; } return cmsg - (const char *)msg; }
void p_stdinit(void (*on_stdin)(char *input_line)) { u_stdin = on_stdin; u_event_src(0, &u_fd0_ready, (void *)0); }