int cl_wait_cmd(const struct cl_cmd_t *cl_cmd, long sec, long usec, int *err) { struct cl_line l; int i; *err = CL_ERR_SUCCESS; if (cl_select(sec, usec, err) < 0) return -1; memset(&l, 0, sizeof(struct cl_line)); if (cl_read(&l, err) < 0) return -1; if (0 != strcasecmp(l.mode, "CMD")) { *err = CL_ERR_SYNTAX; cl_log(CL_LOG_ERR, CL_ERR_SYNTAX); return -1; } for (i = 0; i < CL_CMD_MAX; i++) { if (NULL == cl_cmd[i].name) break; if (0 == strcasecmp(l.key, cl_cmd[i].name)) { if (cl_cmd[i].handler(l.val, err) < 0) { cl_log(CL_LOG_ERR, *err); return -1; } if (CL_ERR_SUCCESS == *err) cl_log(CL_LOG_INFO, CL_ERR_SUCCESS); else cl_log(CL_LOG_ERR, *err); return 0; } } cl_log(CL_LOG_ERR, CL_ERR_UNKCMD); return -1; }
/* * cl_event -- * Return a single event. * * PUBLIC: int cl_event __P((SCR *, EVENT *, u_int32_t, int)); */ int cl_event(SCR *sp, EVENT *evp, u_int32_t flags, int ms) { struct timeval t, *tp; CL_PRIVATE *clp; size_t lines, columns; int changed, nr = 0; CHAR_T *wp; size_t wlen; int rc; /* * Queue signal based events. We never clear SIGHUP or SIGTERM events, * so that we just keep returning them until the editor dies. */ clp = CLP(sp); retest: if (LF_ISSET(EC_INTERRUPT) || F_ISSET(clp, CL_SIGINT)) { if (F_ISSET(clp, CL_SIGINT)) { F_CLR(clp, CL_SIGINT); evp->e_event = E_INTERRUPT; } else evp->e_event = E_TIMEOUT; return (0); } if (F_ISSET(clp, CL_SIGHUP | CL_SIGTERM | CL_SIGWINCH)) { if (F_ISSET(clp, CL_SIGHUP)) { evp->e_event = E_SIGHUP; return (0); } if (F_ISSET(clp, CL_SIGTERM)) { evp->e_event = E_SIGTERM; return (0); } if (F_ISSET(clp, CL_SIGWINCH)) { F_CLR(clp, CL_SIGWINCH); if (cl_ssize(sp, 1, &lines, &columns, &changed)) return (1); if (changed) { (void)cl_resize(sp, lines, columns); evp->e_event = E_WRESIZE; return (0); } /* No real change, ignore the signal. */ } } /* Set timer. */ if (ms == 0) tp = NULL; else { t.tv_sec = ms / 1000; t.tv_usec = (ms % 1000) * 1000; tp = &t; } /* Read input characters. */ read: switch (cl_read(sp, LF_ISSET(EC_QUOTED | EC_RAW), clp->ibuf + clp->skip, SIZE(clp->ibuf) - clp->skip, &nr, tp)) { case INP_OK: rc = INPUT2INT5(sp, clp->cw, clp->ibuf, nr + clp->skip, wp, wlen); evp->e_csp = wp; evp->e_len = wlen; evp->e_event = E_STRING; if (rc < 0) { int n = -rc; memmove(clp->ibuf, clp->ibuf + nr + clp->skip - n, n); clp->skip = n; if (wlen == 0) goto read; } else if (rc == 0) clp->skip = 0; else msgq(sp, M_ERR, "323|Invalid input. Truncated."); break; case INP_EOF: evp->e_event = E_EOF; break; case INP_ERR: evp->e_event = E_ERR; break; case INP_INTR: goto retest; case INP_TIMEOUT: evp->e_event = E_TIMEOUT; break; default: abort(); } return (0); }