Hi,
attached is a patch with a couple of related fixes to TTY handling.
The patch was need to make DFB work in my setup when running DFB
applications both as root and as unprivileged user and both from the
physical terminal (/dev/tty1) and SSH login shell. Part of it is, I'm
sorry to say, reversal of changes I suggested (these two revisions:
http://directfb.org/index.php/viewcvs.cgi/DirectFB/systems/fbdev/fbdev.c.diff?r1=1.49&r2=1.51).
Here's more detailed description of the changes:
* Previously, the process attached itself to a new controlling TTY
only if vt_switch option was on. This patch changes it to always
(unless VT handling is completely disabled, of course) attach the
process to the TTY being used by the app as the new controlling TTY.
This is because we always need some controlling TTY, without it, there
could be SIGHUP/SIGCONT signals (see e.g. my post about re-adding
setpgid() call). Note that the patch moves TIOCSCTTY call outside
of "if vt-switch" branch, but completely removes TIOCNOTTY - - that's
because the latter is not needed, setsid() already detached the
process from controlling TTY. So "vt-switch" now only
controls "physical" change of the currently active console.
* /dev/tty? files are opened with O_NOCTTY. Linux kernel has a feature
that if a process without controlling TTY opens a TTY device, it's
made its controlling TTY, unless you use O_NOCTTY, so this change
ensure that we only attach to the desired TTY explicitly using
TIOCSCTTY.
* Moved TIOCSCTTY before KBSETMODE use, otherwise non-root users get
EPERM from KBSETMODE ioctl(), because you can't do that operation on
anything other than your controlling TTY normally.
* Removed setpgid() calls, because they interfered with setsid() later
and weren't really necessary now that other cTTY problems were fixed.
Ditto for the removed dfb_vt_detach() call (I couldn't find any
information about why it was there in the first place, but everything
works without it as far as I can tell).
I'm not sure if you'll want to include it in 1.0.0: on one hand, it
fixes a serious problem with running as non-root user, on the other
hand, it's not trivial change and may have some consequences I
missed. I'd certainly appreciate a review of the patch, I'm still
quite unfamiliar with the DFB code.
Regards,
Vaclav
--
PGP key: 0x465264C9, available from http://pgp.mit.edu/
Index: src/DirectFB/systems/fbdev/fbdev.c
===================================================================
--- src/DirectFB/systems/fbdev/fbdev.c (revision 139)
+++ src/DirectFB/systems/fbdev/fbdev.c (revision 143)
@@ -439,8 +439,6 @@
shared->page_mask = page_size < 0 ? 0 : (page_size - 1);
- setpgid( 0, 0 );
-
ret = dfb_fbdev_open();
if (ret)
goto error;
@@ -613,8 +611,6 @@
dfb_fbdev->core = core;
dfb_fbdev->shared = shared;
- setpgid( 0, 0 );
-
/* Open framebuffer device */
ret = dfb_fbdev_open();
if (ret) {
@@ -833,9 +829,6 @@
if (dfb_config->block_all_signals)
direct_signals_block_all();
- if (dfb_config->vt)
- return dfb_vt_detach( false );
-
return DFB_OK;
}
Index: src/DirectFB/systems/fbdev/vt.c
===================================================================
--- src/DirectFB/systems/fbdev/vt.c (revision 139)
+++ src/DirectFB/systems/fbdev/vt.c (revision 143)
@@ -104,10 +104,10 @@
dfb_vt = D_CALLOC( 1, sizeof(VirtualTerminal) );
setsid();
- dfb_vt->fd0 = open( "/dev/tty0", O_RDONLY );
+ dfb_vt->fd0 = open( "/dev/tty0", O_RDONLY | O_NOCTTY );
if (dfb_vt->fd0 < 0) {
if (errno == ENOENT) {
- dfb_vt->fd0 = open( "/dev/vc/0", O_RDONLY );
+ dfb_vt->fd0 = open( "/dev/vc/0", O_RDONLY | O_NOCTTY );
if (dfb_vt->fd0 < 0) {
if (errno == ENOENT) {
D_PERROR( "DirectFB/core/vt: Couldn't open "
@@ -325,7 +325,7 @@
int fd;
struct vt_stat vt_state;
- fd = open( "/dev/tty", O_RDONLY );
+ fd = open( "/dev/tty", O_RDONLY | O_NOCTTY );
if (fd < 0) {
if (errno == ENXIO)
return DFB_OK;
@@ -441,11 +441,11 @@
/* FIXME: Opening the device should be moved out of this function. */
snprintf(buf, 32, "/dev/tty%d", dfb_vt->num);
- dfb_vt->fd = open( buf, O_RDWR );
+ dfb_vt->fd = open( buf, O_RDWR | O_NOCTTY );
if (dfb_vt->fd < 0) {
if (errno == ENOENT) {
snprintf(buf, 32, "/dev/vc/%d", dfb_vt->num);
- dfb_vt->fd = open( buf, O_RDWR );
+ dfb_vt->fd = open( buf, O_RDWR | O_NOCTTY );
if (dfb_vt->fd < 0) {
if (errno == ENOENT) {
D_PERROR( "DirectFB/core/vt: Couldn't open "
@@ -466,6 +466,10 @@
}
}
+ /* attach to the new TTY before doing anything like KDSETMODE with it,
+ otherwise we'd get access denied error: */
+ ioctl( dfb_vt->fd, TIOCSCTTY, 0 );
+
write( dfb_vt->fd, cursoroff_str, sizeof(cursoroff_str) );
if (dfb_config->kd_graphics) {
if (ioctl( dfb_vt->fd, KDSETMODE, KD_GRAPHICS ) < 0) {
@@ -478,11 +482,6 @@
write( dfb_vt->fd, blankoff_str, sizeof(blankoff_str) );
}
- if (dfb_config->vt_switch) {
- ioctl( dfb_vt->fd0, TIOCNOTTY, 0 );
- ioctl( dfb_vt->fd, TIOCSCTTY, 0 );
- }
-
if (dfb_config->vt_switching) {
struct vt_mode vt;
struct sigaction sig_tty;
_______________________________________________
directfb-dev mailing list
[email protected]
http://mail.directfb.org/cgi-bin/mailman/listinfo/directfb-dev