From fb08eea3737907bbbc11c0a14427efe116fae92e Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Wed, 6 Mar 2013 19:03:34 +0100 Subject: [PATCH] uvtd: vt: implement VT_GETMODE/SETMODE ioctl state-tracking These ioctls are used to retrieve and set the VT-mode. That is, the signals and PID information that correspond to the VT controlling process. It is notified whenever the VT gets active/inactive so it can react to it or prevent/acknowledge it. This doesn't implement the signal-sending logic, yet. It only implements state-tracking. Signed-off-by: David Herrmann --- src/uvt.h | 3 ++- src/uvt_client.c | 3 ++- src/uvtd_vt.c | 41 ++++++++++++++++++++++++++++++++++++++--- 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/src/uvt.h b/src/uvt.h index a69dd6f..e767005 100644 --- a/src/uvt.h +++ b/src/uvt.h @@ -108,7 +108,8 @@ struct uvt_vt_ops { int (*ioctl_VT_GETSTATE) (void *data, struct vt_stat *arg); int (*ioctl_VT_OPENQRY) (void *data, unsigned int *arg); int (*ioctl_VT_GETMODE) (void *data, struct vt_mode *arg); - int (*ioctl_VT_SETMODE) (void *data, const struct vt_mode *arg); + int (*ioctl_VT_SETMODE) (void *data, const struct vt_mode *arg, + pid_t pid); int (*ioctl_VT_RELDISP) (void *data, unsigned long arg); int (*ioctl_KDGETMODE) (void *data, unsigned int *arg); int (*ioctl_KDSETMODE) (void *data, unsigned int arg); diff --git a/src/uvt_client.c b/src/uvt_client.c index d31a35b..574001e 100644 --- a/src/uvt_client.c +++ b/src/uvt_client.c @@ -972,7 +972,8 @@ void uvt_client_ll_ioctl(fuse_req_t req, int cmd, void *arg, fuse_reply_err(req, EOPNOTSUPP); } else { ret = client->vt->ioctl_VT_SETMODE(client->vt_data, - (const struct vt_mode*)in_buf); + (const struct vt_mode*)in_buf, + fuse_req_ctx(req)->pid); if (ret) fuse_reply_err(req, abs(ret)); else diff --git a/src/uvtd_vt.c b/src/uvtd_vt.c index 18e4503..cc121a0 100644 --- a/src/uvtd_vt.c +++ b/src/uvtd_vt.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -55,6 +56,8 @@ struct uvtd_vt { unsigned int mode; unsigned int kbmode; + struct vt_mode vtmode; + pid_t vtpid; }; static void vt_hup(struct uvtd_vt *vt) @@ -107,6 +110,7 @@ int uvtd_vt_new(struct uvtd_vt **out, struct uvt_ctx *uctx, unsigned int id, vt->is_legacy = is_legacy; vt->mode = KD_TEXT; vt->kbmode = K_UNICODE; + vt->vtmode.mode = VT_AUTO; ret = shl_hook_new(&vt->hook); if (ret) @@ -214,12 +218,43 @@ static int vt_ioctl_VT_OPENQRY(void *data, unsigned int *arg) static int vt_ioctl_VT_GETMODE(void *data, struct vt_mode *arg) { - return -EINVAL; + struct uvtd_vt *vt = data; + + memcpy(arg, &vt->vtmode, sizeof(*arg)); + return 0; } -static int vt_ioctl_VT_SETMODE(void *data, const struct vt_mode *arg) +static int vt_ioctl_VT_SETMODE(void *data, const struct vt_mode *arg, + pid_t pid) { - return -EINVAL; + struct uvtd_vt *vt = data; + + /* TODO: implement waitv logic (hang on write if not active) */ + if (arg->waitv) + return -EOPNOTSUPP; + + if (arg->frsig) + return -EINVAL; + if (arg->relsig > SIGRTMAX || arg->relsig < 0) + return -EINVAL; + if (arg->acqsig > SIGRTMAX || arg->acqsig < 0) + return -EINVAL; + + switch (arg->mode) { + case VT_AUTO: + if (arg->acqsig || arg->relsig) + return -EINVAL; + vt->vtpid = 0; + break; + case VT_PROCESS: + vt->vtpid = pid; + break; + default: + return -EINVAL; + } + + memcpy(&vt->vtmode, arg, sizeof(*arg)); + return 0; } static int vt_ioctl_VT_RELDISP(void *data, unsigned long arg) -- 2.7.4