#include <errno.h>
#include <fcntl.h>
-#include <linux/vt.h>
#include <linux/kd.h>
+#include <linux/vt.h>
#include <signal.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include "sd-messages.h"
-#include "util.h"
-#include "mkdir.h"
-#include "path-util.h"
-#include "fileio.h"
+
#include "audit.h"
-#include "bus-util.h"
#include "bus-error.h"
-#include "logind-session.h"
+#include "bus-util.h"
+#include "escape.h"
+#include "fd-util.h"
+#include "fd-util.h"
+#include "fileio.h"
#include "formats-util.h"
+#include "io-util.h"
+#include "logind-session.h"
+#include "mkdir.h"
+#include "parse-util.h"
+#include "path-util.h"
#include "terminal-util.h"
+#include "user-util.h"
+#include "util.h"
#define RELEASE_USEC (20*USEC_PER_SEC)
if (s->fifo_path) {
unlink(s->fifo_path);
- free(s->fifo_path);
- s->fifo_path = NULL;
+ s->fifo_path = mfree(s->fifo_path);
}
}
return s->vtfd;
sprintf(path, "/dev/tty%u", s->vtnr);
- s->vtfd = open(path, O_RDWR | O_CLOEXEC | O_NONBLOCK | O_NOCTTY);
+ s->vtfd = open_terminal(path, O_RDWR | O_CLOEXEC | O_NONBLOCK | O_NOCTTY);
if (s->vtfd < 0)
return log_error_errno(errno, "cannot open VT %s of session %s: %m", path, s->id);
r = fchown(vt, s->user->uid, -1);
if (r < 0) {
- r = -errno;
- log_error_errno(errno, "Cannot change owner of /dev/tty%u: %m", s->vtnr);
+ r = log_error_errno(errno,
+ "Cannot change owner of /dev/tty%u: %m",
+ s->vtnr);
goto error;
}
r = ioctl(vt, KDSKBMODE, K_OFF);
if (r < 0) {
- r = -errno;
- log_error_errno(errno, "Cannot set K_OFF on /dev/tty%u: %m", s->vtnr);
+ r = log_error_errno(errno,
+ "Cannot set K_OFF on /dev/tty%u: %m",
+ s->vtnr);
goto error;
}
r = ioctl(vt, KDSETMODE, KD_GRAPHICS);
if (r < 0) {
- r = -errno;
- log_error_errno(errno, "Cannot set KD_GRAPHICS on /dev/tty%u: %m", s->vtnr);
+ r = log_error_errno(errno,
+ "Cannot set KD_GRAPHICS on /dev/tty%u: %m",
+ s->vtnr);
goto error;
}
mode.acqsig = SIGRTMIN + 1;
r = ioctl(vt, VT_SETMODE, &mode);
if (r < 0) {
- r = -errno;
- log_error_errno(errno, "Cannot set VT_PROCESS on /dev/tty%u: %m", s->vtnr);
+ r = log_error_errno(errno,
+ "Cannot set VT_PROCESS on /dev/tty%u: %m",
+ s->vtnr);
goto error;
}
}
void session_restore_vt(Session *s) {
+
+ static const struct vt_mode mode = {
+ .mode = VT_AUTO,
+ };
+
_cleanup_free_ char *utf8 = NULL;
- int vt, kb = K_XLATE;
- struct vt_mode mode = { 0 };
+ int vt, kb, old_fd;
+
+ /* We need to get a fresh handle to the virtual terminal,
+ * since the old file-descriptor is potentially in a hung-up
+ * state after the controlling process exited; we do a
+ * little dance to avoid having the terminal be available
+ * for reuse before we've cleaned it up.
+ */
+ old_fd = s->vtfd;
+ s->vtfd = -1;
vt = session_open_vt(s);
+ safe_close(old_fd);
+
if (vt < 0)
return;
if (read_one_line_file("/sys/module/vt/parameters/default_utf8", &utf8) >= 0 && *utf8 == '1')
kb = K_UNICODE;
+ else
+ kb = K_XLATE;
(void) ioctl(vt, KDSKBMODE, kb);
- mode.mode = VT_AUTO;
(void) ioctl(vt, VT_SETMODE, &mode);
-
- fchown(vt, 0, -1);
+ (void) fchown(vt, 0, (gid_t) -1);
s->vtfd = safe_close(s->vtfd);
}