Understanding Unix Devices and Signals

Unix Internals:


Devices

In a Unix system, every device is treated as a file. Every device has a filename, an inode number, an owner, a set of permission bets, and a last-modified time. By tradition, files that represent devices are in the /dev directory, but you can crate devices files in any directory.

[root@ipc4 ~]# ls -il /dev/ | head -20
total 0
3729 crw-rw---- 1 root root 14, 12 Oct 30 02:42 adsp
439 crw------- 1 root root 10, 175 Oct 30 02:41 agpgart
443 crw------- 1 root root 36, 8 Oct 30 02:41 arpd
3907 crw------- 1 root root 14, 4 Oct 30 02:42 audio
2682 lrwxrwxrwx 1 root root 3 Oct 30 02:42 cdrom -> hdc
2684 lrwxrwxrwx 1 root root 3 Oct 30 02:42 cdwriter -> hdc
398 crw------- 1 root root 5, 1 Oct 30 10:45 console
1532 lrwxrwxrwx 1 root root 11 Oct 30 02:42 core -> /proc/kcore
839 crw------- 1 root root 10, 63 Oct 30 02:41 device-mapper
893 brw-r----- 1 root root 253, 0 Oct 30 02:41 dm-0
911 brw-r----- 1 root root 253, 1 Oct 30 02:41 dm-1
3728 crw-rw---- 1 root root 14, 9 Oct 30 02:42 dmmidi
445 crw------- 1 root root 36, 14 Oct 30 02:41 dnrtmsg
3877 crw------- 1 root root 14, 3 Oct 30 02:42 dsp
2683 lrwxrwxrwx 1 root root 3 Oct 30 02:42 dvd -> hdc
2685 lrwxrwxrwx 1 root root 3 Oct 30 02:42 dvdwriter -> hdc
431 crw------- 1 root root 13, 64 Oct 30 02:41 event0
433 crw------- 1 root root 13, 65 Oct 30 02:41 event1
1528 lrwxrwxrwx 1 root root 13 Oct 30 02:42 fd -> /proc/self/fd

Properties of Device Files

Device files have most of the properties disk files have. Below 'ls' and 'stat' commands shows the properties of a terminal /dev/pts/3 (see your current terminal by 'tty' command), it has inode number 5, permission is crw--w----, owned by root, group is 'tty', 'filesize' last modification time is Nov 1, 13:05. Note the filesize field is 136,3 instead of a regular file's size. This is because the inode of a device file stores, not a a file size and storage list (points pointing the data blocks), it stores a pointer to a subroutine in the kernel, which is called device driver. 136,3 means the device driver is subroutine number 136 in a table of device-processing code. 3 is the argument passed to the device-process code. 136 is also called a device's major number and 3 is called minor number.

Note the permission bit for pts/3, only owner can read from the file (terminal) and all others can write into it. In the example below, we can copy message of the day file to a terminal.


Device file's filetype is also stored in inode's st_mode field.





Questions - What's the command to dump your terminal to another one (assume you have permission to write to)? e.g. when you type "ls -l", it shows on your terminal and also on user's terminal simultaneously?

What you do to just show the command's output not the command itself?

How to turn on auditing mode to peek other's terminal without letting the users know?

Answers are at the end of this blog article.


[root@ipc4 ~]# ls -il /dev/pts/3
5 crw--w---- 1 root tty 136, 3 Nov 1 13:05 /dev/pts/3

[root@ipc4 ~]# stat /dev/pts/3
File: `/dev/pts/3'
Size: 0 Blocks: 0 IO Block: 1024 character special file
Device: 9h/9d Inode: 5 Links: 1 Device type: 88,3
Access: (0620/crw--w----) Uid: ( 0/ root) Gid: ( 5/ tty)
Access: 2009-11-01 13:00:58.022207816 -0800
Modify: 2009-11-01 13:00:58.022207816 -0800
Change: 2009-11-01 12:43:13.992842432 -0800



[root@ipc4 ~]# tty
/dev/pts/3

[root@ipc4 ~]# cp /etc/motd /dev/pts/3

This is a restricted Linux server running on a vmware inside Shan's laptop.



[root@ipc4 ~]# write shan /dev/pts/2

Message from root@ipc4.shanjing.com on pts/3 at 13:21 ...
Do you copy?
Do you copy?


Signals:

A signal is a one-word messages sent by kernel requested by one of the three sources:
users (control -C, sends signal code 2),
kernel ( segmentation violation),
processes (use kill system call).

Signal Value Action Comment
-------------------------------------------------------------------------
SIGHUP 1 Term Hangup detected on controlling terminal
or death of controlling process
SIGINT 2 Term Interrupt from keyboard
SIGQUIT 3 Core Quit from keyboard
SIGILL 4 Core Illegal Instruction
SIGABRT 6 Core Abort signal from abort(3)
SIGFPE 8 Core Floating point exception
SIGKILL 9 Term Kill signal
SIGSEGV 11 Core Invalid memory reference
SIGPIPE 13 Term Broken pipe: write to pipe with no readers
SIGALRM 14 Term Timer signal from alarm(2)
SIGTERM 15 Term Termination signal
SIGUSR1 30,10,16 Term User-defined signal 1
SIGUSR2 31,12,17 Term User-defined signal 2
SIGCHLD 20,17,18 Ign Child stopped or terminated
SIGCONT 19,18,25 Continue if stopped
SIGSTOP 17,19,23 Stop Stop process
SIGTSTP 18,20,24 Stop Stop typed at tty
SIGTTIN 21,21,26 Stop tty input for background process
SIGTTOU 22,22,27 Stop tty output for background process


Job Control on Unix

control-z Stop (don't kill) the foreground job, and then return to the shell
jobs Check the status of jobs in the current session
ps -u username Check the status of processes, including those from other sessions. On BSD systems, use 'ps -gx'.
kill -9 %1 Kill a job, by specifying its job number after the percent sign
kill -9 123 Kill a process, by specifying its process id (PID) number
bg Run the most recently stopped job in the background
fg Bring most recently backgrounded job to the foreground
fg %1 Bring a job to foreground by specifying its job number after the percent sign
[shan@ipc4 uulp]$ ps -u shan
PID TTY TIME CMD
3659 ? 00:00:04 sshd
3660 pts/0 00:00:00 bash
6641 ? 00:00:00 sshd
6642 pts/2 00:00:00 bash
6773 ? 00:00:01 sshd
6774 pts/1 00:00:00 bash
6949 ? 00:00:00 sshd
6950 pts/4 00:00:00 bash
7099 pts/4 00:00:00 ps
[1]+ Exit 228 ./signal

[shan@ipc4 uulp]$ gcc -o job-1 signal.c
[shan@ipc4 uulp]$ ./job-1 &
[1] 7109
[shan@ipc4 uulp]$ jobs -l
[1]+ 7109 Running ./job-1 &

[shan@ipc4 uulp]$ fg %1
./job-1

(control Z to stop/suspend the job but don't kill)
[1]+ Stopped ./job-1
[shan@ipc4 uulp]$ jobs -l
[1]+ 7109 Stopped ./job-1

(bring it to background)
[shan@ipc4 uulp]$ bg %1
[1]+ ./job-1 &

[shan@ipc4 uulp]$ jobs -l
[1]+ 7109 Running ./job-1 &


Ignoring Control -C (SIGINT) signal:

[shan@ipc4 uulp]$ cat ignore.c
/* ignore.c - shows how to ignore a signal
* - press Ctrl-\ to kill this one
*/

#include
#include

main()
{
signal( SIGINT, SIG_IGN );

printf("you can't stop me!\n");
while( 1 )
{
sleep(1);
printf("haha\n");
}
}
[shan@ipc4 uulp]$ ./ignore
you can't stop me!
haha

haha
haha
haha
haha
^_Quit





Answers to the questions:

To dump your terminal to pts/3,
script -a /dev/null | tee /dev/pts/3

stty -echo

use script's -q option (Linux and AIX both implemented, but not on Solaris)