static int connect_eloop(struct kmscon_vt *vt, struct ev_eloop *eloop) { int ret; if (!vt || !eloop || vt->fd < 0) return -EINVAL; ret = ev_eloop_register_signal_cb(eloop, SIGUSR1, vt_leave, vt); if (ret) return ret; ret = ev_eloop_register_signal_cb(eloop, SIGUSR2, vt_enter, vt); if (ret) goto err_sig1; ret = ev_eloop_new_fd(eloop, &vt->efd, vt->fd, EV_READABLE, vt_input, vt); if (ret) goto err_sig2; vt->eloop = eloop; ev_eloop_ref(vt->eloop); return 0; err_sig2: ev_eloop_unregister_signal_cb(vt->eloop, SIGUSR2, vt_enter, vt); err_sig1: ev_eloop_unregister_signal_cb(vt->eloop, SIGUSR1, vt_leave, vt); return ret; }
int kmscon_pty_open(struct kmscon_pty *pty, unsigned short width, unsigned short height) { int ret; int master; if (!pty) return -EINVAL; if (pty_is_open(pty)) return -EALREADY; master = posix_openpt(O_RDWR | O_NOCTTY | O_CLOEXEC | O_NONBLOCK); if (master < 0) { log_err("cannot open master: %m"); return -errno; } ret = ev_eloop_new_fd(pty->eloop, &pty->efd, master, EV_READABLE, pty_input, pty); if (ret) goto err_master; ret = ev_eloop_register_signal_cb(pty->eloop, SIGCHLD, sig_child, pty); if (ret) goto err_fd; ret = pty_spawn(pty, master, width, height); if (ret) goto err_sig; return 0; err_sig: ev_eloop_unregister_signal_cb(pty->eloop, SIGCHLD, sig_child, pty); err_fd: ev_eloop_rm_fd(pty->efd); pty->efd = NULL; err_master: close(master); return ret; }
static int video_init(struct uterm_video *video, const char *node) { int ret; struct dumb_video *dumb = &video->dumb; uint64_t has_dumb; log_info("probing %s", node); dumb->fd = open(node, O_RDWR | O_CLOEXEC); if (dumb->fd < 0) { log_err("cannot open drm device %s (%d): %m", node, errno); return -EFAULT; } drmDropMaster(dumb->fd); if (drmGetCap(dumb->fd, DRM_CAP_DUMB_BUFFER, &has_dumb) < 0 || !has_dumb) { log_err("driver does not support dumb buffers"); ret = -EFAULT; goto err_close; } ret = ev_eloop_new_fd(video->eloop, &dumb->efd, dumb->fd, EV_READABLE, event, video); if (ret) goto err_close; video->flags |= VIDEO_HOTPLUG; log_info("new drm device via %s", node); return 0; err_close: close(dumb->fd); return ret; }
static int setup_app(struct uvtd_app *app) { int ret, fd; shl_dlist_init(&app->seats); ret = ev_eloop_new(&app->eloop, log_llog, NULL); if (ret) { log_error("cannot create eloop object: %d", ret); goto err_app; } ret = ev_eloop_register_signal_cb(app->eloop, SIGTERM, app_sig_generic, app); if (ret) { log_error("cannot register SIGTERM signal handler: %d", ret); goto err_app; } ret = ev_eloop_register_signal_cb(app->eloop, SIGINT, app_sig_generic, app); if (ret) { log_error("cannot register SIGINT signal handler: %d", ret); goto err_app; } ret = ev_eloop_register_signal_cb(app->eloop, SIGPIPE, app_sig_ignore, app); if (ret) { log_error("cannot register SIGPIPE signal handler: %d", ret); goto err_app; } ret = uterm_monitor_new(&app->mon, app->eloop, app_monitor_event, app); if (ret) { log_error("cannot create device monitor: %d", ret); goto err_app; } ret = uvt_ctx_new(&app->ctx, log_llog, NULL); if (ret) { log_error("cannot create UVT context: %d", ret); goto err_app; } fd = uvt_ctx_get_fd(app->ctx); if (fd >= 0) { ret = ev_eloop_new_fd(app->eloop, &app->ctx_fd, fd, EV_READABLE, app_ctx_event, app); if (ret) { log_error("cannot create UVT ctx efd: %d", ret); goto err_app; } } log_debug("scanning for devices..."); uterm_monitor_scan(app->mon); return 0; err_app: destroy_app(app); return ret; }
static int real_open(struct uterm_vt *vt) { struct termios raw_attribs; struct vt_mode mode; struct vt_stat vts; int ret; sigset_t mask; log_debug("open vt %p", vt); ret = open_tty(-1, &vt->real_fd, &vt->real_num); if (ret) return ret; ret = ev_eloop_new_fd(vt->vtm->eloop, &vt->real_efd, vt->real_fd, EV_READABLE, real_input, vt); if (ret) goto err_fd; /* * Get the number of the VT which is active now, so we have something * to switch back to in kmscon_vt_switch_leave. */ ret = ioctl(vt->real_fd, VT_GETSTATE, &vts); if (ret) { log_warn("cannot find the currently active VT"); vt->real_saved_num = -1; } else { vt->real_saved_num = vts.v_active; } if (tcgetattr(vt->real_fd, &vt->real_saved_attribs) < 0) { log_err("cannot get terminal attributes"); ret = -EFAULT; goto err_eloop; } /* Ignore control characters and disable echo */ raw_attribs = vt->real_saved_attribs; cfmakeraw(&raw_attribs); /* Fix up line endings to be normal (cfmakeraw hoses them) */ raw_attribs.c_oflag |= OPOST | OCRNL; if (tcsetattr(vt->real_fd, TCSANOW, &raw_attribs) < 0) log_warn("cannot put terminal into raw mode"); if (ioctl(vt->real_fd, KDSETMODE, KD_GRAPHICS)) { log_err("vt: cannot set graphics mode\n"); ret = -errno; goto err_reset; } memset(&mode, 0, sizeof(mode)); mode.mode = VT_PROCESS; mode.acqsig = SIGUSR1; mode.relsig = SIGUSR2; if (ioctl(vt->real_fd, VT_SETMODE, &mode)) { log_err("cannot take control of vt handling"); ret = -errno; goto err_text; } sigemptyset(&mask); sigaddset(&mask, SIGUSR1); sigaddset(&mask, SIGUSR2); sigprocmask(SIG_BLOCK, &mask, NULL); return 0; err_text: ioctl(vt->real_fd, KDSETMODE, KD_TEXT); err_reset: tcsetattr(vt->real_fd, TCSANOW, &vt->real_saved_attribs); err_eloop: ev_eloop_rm_fd(vt->real_efd); vt->real_efd = NULL; err_fd: close(vt->real_fd); return ret; }