Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 3 Jul 2001 15:25:24 +0300
From:      Ruslan Ermilov <ru@FreeBSD.ORG>
To:        Bruce Evans <bde@zeta.org.au>
Cc:        Alfred Perlstein <bright@sneakerz.org>, current@FreeBSD.ORG
Subject:   Re: TIOCSCTTY
Message-ID:  <20010703152523.C39090@sunbay.com>
In-Reply-To: <Pine.BSF.4.21.0107031943440.39888-100000@besplex.bde.org>; from bde@zeta.org.au on Tue, Jul 03, 2001 at 07:53:08PM %2B1000
References:  <20010702111904.O84523@sneakerz.org> <Pine.BSF.4.21.0107031943440.39888-100000@besplex.bde.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, Jul 03, 2001 at 07:53:08PM +1000, Bruce Evans wrote:
> On Mon, 2 Jul 2001, Alfred Perlstein wrote:
> 
> > * Ruslan Ermilov <ru@FreeBSD.org> [010702 10:51] wrote:
> > > Hi!
> > > 
> > > Could someone please explain why the following code snippet
> > > does not work anymore with the "/dev/console" argument?
> > > 
> > > # ./tiocsctty /dev/console
> > > tiocsctty: ioctl(/dev/console, TIOCSCTTY): Operation not permitted
> 
> This still works here.  Perhaps another process has aquired /dev/console
> as its controlling terminal.
> 
Weird.  I figured out what causes this, it's moused(8).  I have inserted
some debug code into it to see what's going on:

This is the "ps axjww" and "pstat -t" output before moused(8) calls
daemon(3):

USER     PID  PPID  PGID   SESS JOBC STAT  TT       TIME COMMAND
root       0     0     0 241c60    0 DLs   ??    0:00.00  (swapper)
root       1     0     1 b14840    0 SLs   ??    0:00.00 /sbin/init --
root       2     0     0 241c60    0 DL    ??    0:00.00  (pagedaemon)
root       3     0     0 241c60    0 DL    ??    0:00.00  (vmdaemon)
root       4     0     0 241c60    0 DL    ??    0:00.00  (bufdaemon)
root       5     0     0 241c60    0 DL    ??    0:00.00  (syncer)
root      26     1    26 b75fc0    0 Ss    ??    0:00.00 adjkerntz -i
root     128     1   128 b75340    0 Ss    ??    0:00.00 /sbin/natd -n rl0
root     149     1   149 b753c0    0 Ss    ??    0:00.03 syslogd -s
daemon   156     1   156 b801c0    0 Ss    ??    0:00.00 /usr/sbin/portmap
root     162     1   162 b92940    0 Ss    ??    0:00.01 amd -p -a /.amd_mnt -l syslog /host /etc/amd.map
root     179     1   179 b92200    0 Ss    ??    0:00.01 /usr/sbin/cron
root     182     1   182 bf8ec0    0 Ss    ??    0:00.96 /usr/sbin/sshd
root       6     1     6 b14700    0 Ss+  con    0:00.13 sh /etc/rc autoboot
root     214     6     6 b14700    0 S+   con    0:00.01 moused -3 -p /dev/cuaa1 -t auto
root     218   214     6 b14700    0 S+   con    0:00.00 sh -c (ps axjww; pstat -t) >>/1
root     219   218     6 b14700    0 S+   con    0:00.00 sh -c (ps axjww; pstat -t) >>/1
root     220   219     6 b14700    0 R+   con    0:00.00 ps axjww

  LINE RAW CAN OUT IHIWT ILOWT OHWT LWT     COL STATE  SESS      PGID DISC
  cuaa1  0   0   0   512   448  216  60       0 OCcl          0     0 term
consolectl  0   0   0   512   448 1296 256      98 OCc    c0b14700     6 term
      0  0   0   0     0     0    0   0       0 -             0     0 term
  ttyp0  0   0   0     0     0    0   0       0 -             0     0 term
  ttyv0  0   0   0   512   448 1296 256       0 -             0     0 term

As you can see, process 6 (sh /etc/rc autoboot) is the session leader with
/dev/console as the controlling terminal, and the same session is referenced
from the `tty' structure for the consolectl device.

Next, this is after moused(8) calls daemon(3):

USER     PID  PPID  PGID   SESS JOBC STAT  TT       TIME COMMAND
root       0     0     0 241c60    0 DLs   ??    0:00.00  (swapper)
root       1     0     1 b14840    0 SLs   ??    0:00.00 /sbin/init --
root       2     0     0 241c60    0 DL    ??    0:00.00  (pagedaemon)
root       3     0     0 241c60    0 DL    ??    0:00.00  (vmdaemon)
root       4     0     0 241c60    0 DL    ??    0:00.00  (bufdaemon)
root       5     0     0 241c60    0 DL    ??    0:00.00  (syncer)
root      26     1    26 b75fc0    0 Ss    ??    0:00.00 adjkerntz -i
root     128     1   128 b75340    0 Ss    ??    0:00.00 /sbin/natd -n rl0
root     149     1   149 b753c0    0 Ss    ??    0:00.03 syslogd -s
daemon   156     1   156 b801c0    0 Ss    ??    0:00.00 /usr/sbin/portmap
root     162     1   162 b92940    0 Ss    ??    0:00.01 amd -p -a /.amd_mnt -l syslog /host /etc/amd.map
root     179     1   179 b92200    0 Ss    ??    0:00.01 /usr/sbin/cron
root     182     1   182 bf8ec0    0 Ss    ??    0:00.96 /usr/sbin/sshd
root     221     1   221 bf8280    0 Ss    ??    0:00.00 moused -3 -p /dev/cuaa1 -t auto
root     223   221   221 bf8280    0 S     ??    0:00.00 sh -c (ps axjww; pstat -t) >>/1
root     225   223   221 bf8280    0 S     ??    0:00.00 sh -c (ps axjww; pstat -t) >>/1
root     227   225   221 bf8280    0 R     ??    0:00.00 ps axjww
root       6     1     6 b14700    0 Ss+  con    0:00.14 sh /etc/rc autoboot
root     228     6     6 b14700    0 R+   con    0:00.00 sh /etc/rc autoboot

  LINE RAW CAN OUT IHIWT ILOWT OHWT LWT     COL STATE  SESS      PGID DISC
  cuaa1  0   0   0   512   448  216  60       0 OCcl          0     0 term
consolectl  0   0   0   512   448 1296 256     109 OCc    c0b14700     6 term
      0  0   0   0     0     0    0   0       0 -             0     0 term
  ttyp0  0   0   0     0     0    0   0       0 -             0     0 term
  ttyv0  0   0   0   512   448 1296 256       0 -             0     0 term

Nothing has changed re: consolectl.  It still has session c0b14700 (with
the session leader PID = 6) bound to it.

moused(8) becomes a session leader for a new session with address c0bf8280
(note that MSB of the session address is not shown in the ps(1) output).

Next, this is the output after the system has booted into multi-user:

USER     PID  PPID  PGID   SESS JOBC STAT  TT       TIME COMMAND
root       0     0     0 241c60    0 DLs   ??    0:00.00  (swapper)
root       1     0     1 b14840    0 ILs   ??    0:00.01 /sbin/init --
root       2     0     0 241c60    0 DL    ??    0:00.00  (pagedaemon)
root       3     0     0 241c60    0 DL    ??    0:00.00  (vmdaemon)
root       4     0     0 241c60    0 DL    ??    0:00.00  (bufdaemon)
root       5     0     0 241c60    0 DL    ??    0:00.01  (syncer)
root      26     1    26 b75fc0    0 Is    ??    0:00.00 adjkerntz -i
root     128     1   128 b75340    0 Ss    ??    0:00.00 /sbin/natd -n rl0
root     149     1   149 b753c0    0 Ss    ??    0:00.03 syslogd -s
daemon   156     1   156 b801c0    0 Is    ??    0:00.00 /usr/sbin/portmap
root     162     1   162 b92940    0 Ss    ??    0:00.01 amd -p -a /.amd_mnt -l syslog /host /etc/amd.map
root     179     1   179 b92200    0 Is    ??    0:00.01 /usr/sbin/cron
root     182     1   182 bf8ec0    0 Is    ??    0:00.96 /usr/sbin/sshd
root     221     1   221 bf8280    0 Ss    ??    0:00.08 moused -3 -p /dev/cuaa1 -t auto
root     253     1   253 c02bc0    0 Is+   v0    0:00.01 /usr/libexec/getty Pc ttyv0
root     254     1   254 c02b00    0 Is    v1    0:00.06 -csh (csh)
root     265   254   265 c02b00    1 S     v1    0:00.07 deco
root     276   265   276 c02b00    1 S+    v1    0:00.00 sh -c ps axjww >> 11
root     277   276   276 c02b00    1 R+    v1    0:00.00 ps axjww
root     255     1   255 c02a40    0 Is+   v2    0:00.01 /usr/libexec/getty Pc ttyv2
root     256     1   256 c02980    0 Is+   v3    0:00.01 /usr/libexec/getty Pc ttyv3
root     257     1   257 c02940    0 Is+   v4    0:00.01 /usr/libexec/getty Pc ttyv4
root     258     1   258 c02900    0 Is+   v5    0:00.01 /usr/libexec/getty Pc ttyv5
root     259     1   259 c028c0    0 Is+   v6    0:00.01 /usr/libexec/getty Pc ttyv6
root     260     1   260 c02800    0 Is+   v7    0:00.01 /usr/libexec/getty Pc ttyv7
root     261     1   261 c02e00    0 Is+   v8    0:00.01 /usr/libexec/getty Pc ttyv8
root     262     1   262 c02d40    0 Is+   v9    0:00.01 /usr/libexec/getty Pc ttyv9
root     263     1   263 c02c80    0 Is+   va    0:00.01 /usr/libexec/getty Pc ttyva

The session c0b14700 has disappeared from the ps(1) output, but it is still
referenced from the `tty' structure:

  LINE RAW CAN OUT IHIWT ILOWT OHWT LWT     COL STATE  SESS      PGID DISC
  ttyvb  0   0   0   512   448 1296 256       0 -             0     0 term
  ttyva  0   0   0   512   448 2052 256       7 OCc    c0c02c80   263 term
  ttyv9  0   0   0   512   448 2052 256       7 OCc    c0c02d40   262 term
  ttyv8  0   0   0   512   448 2052 256       7 OCc    c0c02e00   261 term
  ttyv7  0   0   0   512   448 2052 256       7 OCc    c0c02800   260 term
  ttyv6  0   0   0   512   448 2052 256       7 OCc    c0c028c0   259 term
  ttyv5  0   0   0   512   448 2052 256       7 OCc    c0c02900   258 term
  ttyv4  0   0   0   512   448 2052 256       7 OCc    c0c02940   257 term
  ttyv3  0   0   0   512   448 2052 256       7 OCc    c0c02980   256 term
  ttyv2  0   0   0   512   448 2052 256       7 OCc    c0c02a40   255 term
  ttyv1  0   0   0   512   448 2052 256       0 OCc    c0c02b00   279 term
  cuaa1  0   0   0   512   448  216  60       0 OCcl          0     0 term
consolectl  0   0   0   512   448 1296 256       0 OCc    c0b14700     0 term
      0  0   0   0     0     0    0   0       0 -             0     0 term
  ttyp0  0   0   0     0     0    0   0       0 -             0     0 term
  ttyv0  0   0   0   512   448 2052 256       7 OCc    c0c02bc0   253 term

If I then kill moused(8), tty's t_session pointer is reset, and the next
TIOCSCTTY call to /dev/console succeeds.  The problem could also be
demonstrated by running the following small program from /etc/rc.local.
It emulates actions performed by moused(8), except moused(8) opens
/dev/consolectl before a call to daemon(3), and this one opens
/dev/consolectl only in a new session.

What I can't understand is how opening a /dev/consolectl in a new session
doesn't allow the t_session tty pointer to be reset that points to another
(not existing) session.

(This is probably somehow relates to the fact that the device's close()
routine is called only on a last reference drop, but I'm not sure.)

Run this from /etc/rc.local:


#include <sys/ioctl.h>
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>

int
main(void)
{
	int fd;

	if (daemon(0, 0) == -1)
		err(1, "daemon");
	if ((fd = open("/dev/consolectl", O_RDWR)) == -1)
		err(1, "open /dev/consolectl");
	for (;;)
		sleep(1000);

	exit(0);
}


Cheers,
-- 
Ruslan Ermilov		Oracle Developer/DBA,
ru@sunbay.com		Sunbay Software AG,
ru@FreeBSD.org		FreeBSD committer,
+380.652.512.251	Simferopol, Ukraine

http://www.FreeBSD.org	The Power To Serve
http://www.oracle.com	Enabling The Information Age

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010703152523.C39090>