コード例 #1
0
ファイル: vt.c プロジェクト: myra/kmscon
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;
}
コード例 #2
0
ファイル: pty.c プロジェクト: myra/kmscon
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;
}
コード例 #3
0
ファイル: uterm_video_dumb.c プロジェクト: microcai/kmscon
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;
}
コード例 #4
0
ファイル: uvtd_main.c プロジェクト: nachokb/kmscon
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;
}
コード例 #5
0
ファイル: uterm_vt.c プロジェクト: ysangkok/kmscon
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;
}