static void process_read_cb(void *ctx, pty_buf_t *buf, bool eof) {
struct pss_tty *pss = (struct pss_tty *) ctx;
pss->pty_buf = buf;
- pss->pty_eof = eof;
+ if (eof && !process_running(pss->process)) {
+ pss->lws_close_status = pss->process->exit_code == 0 ? 1000 : 1006;
+ }
lws_callback_on_writable(pss->wsi);
}
static void process_exit_cb(void *ctx, pty_process *process) {
struct pss_tty *pss = (struct pss_tty *) ctx;
+ pss->process = NULL;
if (process->killed) {
lwsl_notice("process killed with signal %d, pid: %d\n", process->exit_signal, process->pid);
} else {
lwsl_notice("process exited with code %d, pid: %d\n", process->exit_code, process->pid);
- pss->pty_eof = true;
+ pss->lws_close_status = process->exit_code == 0 ? 1000 : 1006;
lws_callback_on_writable(pss->wsi);
}
}
pss->wsi = wsi;
pss->buffer = NULL;
pss->pty_buf = NULL;
+ pss->lws_close_status = LWS_CLOSE_STATUS_NOSTATUS;
if (server->url_arg) {
while (lws_hdr_copy_fragment(wsi, buf, sizeof(buf), WSI_TOKEN_HTTP_URI_ARGS, n++) > 0) {
break;
}
- // read error or client exited, close connection
- if (pss->pty_eof) {
- lws_close_reason(wsi, pss->process->exit_code ? LWS_CLOSE_STATUS_UNEXPECTED_CONDITION : LWS_CLOSE_STATUS_NORMAL, NULL, 0);
+ if (pss->lws_close_status > LWS_CLOSE_STATUS_NOSTATUS) {
+ lws_close_reason(wsi, pss->lws_close_status, NULL, 0);
return 1;
}
}
break;
case RESIZE_TERMINAL:
- if (pss->process == NULL) break;
json_object_put(parse_window_size(pss->buffer + 1, pss->len - 1,
&pss->process->columns, &pss->process->rows));
pty_resize(pss->process);
pty_io_t *io = (pty_io_t *) stream->data;
if (n <= 0) {
if (n == UV_ENOBUFS || n == 0) return;
+ if (n != UV_EOF) printf("== uv_read failed with error %ld: %s\n", n, uv_strerror(n));
io->read_cb(io->ctx, NULL, true);
goto done;
}
}
void pty_pause(pty_process *process) {
+ if (process == NULL) return;
pty_io_t *io = process->io;
if (io->paused) return;
uv_read_stop((uv_stream_t *) io->out);
}
void pty_resume(pty_process *process) {
+ if (process == NULL) return;
pty_io_t *io = process->io;
if (!io->paused) return;
io->out->data = io;
}
int pty_write(pty_process *process, pty_buf_t *buf) {
+ if (process == NULL) return UV_ESRCH;
pty_io_t *io = process->io;
uv_buf_t b = uv_buf_init(buf->base, buf->len);
uv_write_t *req = xmalloc(sizeof(uv_write_t));
}
bool pty_resize(pty_process *process) {
+ if (process == NULL) return false;
if (process->columns <= 0 || process->rows <= 0) return false;
#ifdef _WIN32
COORD size = { (int16_t) process->columns, (int16_t) process->rows };
}
bool pty_kill(pty_process *process, int sig) {
+ if (process == NULL) return false;
process->killed = true;
#ifdef _WIN32
return TerminateProcess(process->handle, 1) != 0;