Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

NEW: Patch to implement ^T process status feature

5 views
Skip to first unread message

David I. Bell

unread,
Feb 24, 1993, 9:29:37 PM2/24/93
to
Here are patches for 0.99.5 to implement a ^T feature for linux. This
feature gives you an instant status report about the most recently running
process on your terminal. The original idea is very old (I saw it on TOPS-10
about 20 years ago). Once you get used to the feature, you probably can't
do without it and want it on every system you use!

Basically, if you are bored with waiting for a compile to finish, or want
to know if there is some problem with a program or the system, then you
simply type a control-T. The linux kernel will intercept this and print back
to your terminal a one-line status message about your most current process.

The message looks similar to the following:

pid 79 (ls) cpu 1.44 mem 73/24 pgft 37 pc 5af running

Included are the process id, the program name, the (kernel+user) cpu time to
hundreths of seconds, the resident and virtual memory sizes in K, the number
of (major+minor) page faults, the user pc (instruction counter), and either
whether the program is running or the reason why it is not running.

This feature works on all terminals, not only on the console (but I haven't
tested that). So you can use it on serial lines, and under X11. The
feature is disabled if the terminal is RAW mode, so that programs that
want every input character should still work. On the console, you can
alternatively use Alt-PrintScreen (SysReq) to obtain the status of the process
even if ^T is disabled by the program. (But not under X11, unfortunately.)

The process that is reported on is the most recently running one that is in
the current process group of the terminal. So if you have a pipeline of
several programs executing in the foreground, then the ^T will report on
whichever of those programs last ran. Typing multiple ^T's in succession
will sample the programs, and show you each of them according to the relative
percentage of times that they run. To get the status of a program running
in the background, simply move it to the foreground and ^T will report on it.

I hope you find this feature useful (and that Linus thinks so too and puts
this into the real distribution, suitably modified of course).


More detailed comments and explanations:

I have made the code dependent on the proc file system (CONFIG_PROC_PS is
true). This isn't necessary, but it was convenient. With a little work,
you could run this code without the proc filesystem. Also the definition
of show_proc_status shouldn't really be in tty.h, but this was also
convenient.

This fixes a bug in the proc file system (in array.c) which obtains the
process's stack size and pc. So these items in the "ps" output which used
to be wrong are also fixed by this patch.

I would like to have more detailed status on disk reading and writing.
This is hard to do with the current linux code, so all you get is the status
of "buffer wait" for both cases. There are some other sleep reasons that
would be nice to know. Currently, I distinguish between tty input and output,
buffer waits, pause, file locks, process waits, swapping, select wait,
running, runable, and a few others. "Runable" means the process is not the
currently running process, but is waiting to run. "Running" means the process
is the currenty running process. When a sleep reason is one that I don't
check for explicitly, you get one of the states of "sleeping" or "io wait".
"Sleeping" means some generic interruptable sleep. "Io wait" means some
generic uninterruptable sleep.

The hardwiring of ^T for displaying process status is not correct. It should
be a configurable character like KILL and EOF. But this involves changes to
many user mode programs, which I did not want to do. So I did a compromise
and make the enabling of ^T dependent on the QUIT character being enabled.
You could remove the check for ^T totally, and only use Alt-PrintScreen if
you want (but then it wouldn't work under X11 or for serial lines).

The newline at the end of the status message is not quite right. It always
prints a carriage return and line feed, whereas it should check the output
mode setting for the terminal and print the appropriate newline sequence.

If the terminal output buffer is almost full, then the ^T request results in
no output. This is not a problem on the console, but could be on a serial
line or under X11. It is very hard under linux to fix the problem, which
would be to allow a little extra room to be reserved to store one of the
status outputs in the output buffer. But this isn't much of a problem in
practice, since with lots of tty output you already know what your program
is doing.

The virtual size and the resident sizes appear to not be correctly calculated
with respect to each other. The resident size is larger than the virtual
size in many cases, for example.

The user mode pc appears very large in many cases. This is NOT wrong.
The pc is really up there, and is simply in one of the shared libraries
which are at high addresses.

---------------------------------------------------------------------------

diff --context --recursive linux-0.99.5.O/fs/buffer.c linux-0.99.5.N/fs/buffer.c
*** linux-0.99.5.O/fs/buffer.c Tue Feb 9 20:07:51 1993
--- linux-0.99.5.N/fs/buffer.c Tue Feb 23 19:11:33 1993
***************
*** 63,68 ****
--- 63,69 ----
add_wait_queue(&bh->b_wait, &wait);
repeat:
current->state = TASK_UNINTERRUPTIBLE;
+ current->waitstr = "buffer wait";
if (bh->b_lock) {
schedule();
goto repeat;
diff --context --recursive linux-0.99.5.O/fs/inode.c linux-0.99.5.N/fs/inode.c
*** linux-0.99.5.O/fs/inode.c Tue Feb 9 20:07:51 1993
--- linux-0.99.5.N/fs/inode.c Tue Feb 23 19:11:03 1993
***************
*** 345,350 ****
--- 345,351 ----
add_wait_queue(&inode->i_wait, &wait);
repeat:
current->state = TASK_UNINTERRUPTIBLE;
+ current->waitstr = "inode wait";
if (inode->i_lock) {
schedule();
goto repeat;
diff --context --recursive linux-0.99.5.O/fs/locks.c linux-0.99.5.N/fs/locks.c
*** linux-0.99.5.O/fs/locks.c Tue Feb 9 20:07:51 1993
--- linux-0.99.5.N/fs/locks.c Thu Feb 25 07:28:54 1993
***************
*** 145,150 ****
--- 145,151 ----
* FIXME: We need to check for deadlocks here.
*/
if (cmd == F_SETLKW) {
+ current->waitstr = "file lock";
interruptible_sleep_on(&fl->fl_wait);
goto repeat;
}
diff --context --recursive linux-0.99.5.O/fs/proc/array.c linux-0.99.5.N/fs/proc/array.c
*** linux-0.99.5.O/fs/proc/array.c Tue Feb 9 20:07:52 1993
--- linux-0.99.5.N/fs/proc/array.c Thu Feb 25 08:51:12 1993
***************
*** 19,26 ****
#define LOAD_INT(x) ((x) >> FSHIFT)
#define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)

! #define KSTK_EIP(stack) (((char *)stack)[1019])
! #define KSTK_ESP(stack) (((char *)stack)[1022])

#define _SSIZE(stack) (TASK_SIZE - KSTK_ESP(stack))
#define SSIZE(stack) (KSTK_ESP(stack) ? _SSIZE(stack) : 0)
--- 19,26 ----
#define LOAD_INT(x) ((x) >> FSHIFT)
#define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)

! #define KSTK_EIP(stack) (((unsigned long *)stack)[1019])
! #define KSTK_ESP(stack) (((unsigned long *)stack)[1022])

#define _SSIZE(stack) (TASK_SIZE - KSTK_ESP(stack))
#define SSIZE(stack) (KSTK_ESP(stack) ? _SSIZE(stack) : 0)
***************
*** 344,349 ****
--- 344,450 ----
file->f_pos = end;
return count;
}
+
+ /*
+ * Print the status of the most recently running process in the specified
+ * terminal's current process group to that terminal.
+ */
+ void
+ show_proc_status(struct tty_struct *tty)
+ {
+ struct task_struct *p, **pp;
+ unsigned long vsize;
+ unsigned long pc;
+ unsigned long runint;
+ int runfrac;
+ char *cp;
+ char runstr[20];
+ static char str[100];
+
+ p = NULL;
+ for (pp = &LAST_TASK ; pp > &FIRST_TASK ; --pp) {
+ if (!*pp || ((*pp)->pgrp != tty->pgrp))
+ continue;
+ if (!p || ((*pp)->runorder > p->runorder))
+ p = *pp;
+ }
+ if (!p) {
+ cp = "No processes in terminal's process group\r\n";
+ goto store;
+ }
+ switch (p->state) {
+ case TASK_RUNNING:
+ if (p == current)
+ cp = "running";
+ else
+ cp = "runable";
+ break;
+ case TASK_INTERRUPTIBLE:
+ cp = "sleep";
+ if (p->waitstr)
+ cp = p->waitstr;
+ break;
+ case TASK_UNINTERRUPTIBLE:
+ cp = "io wait";
+ if (p->waitstr)
+ cp = p->waitstr;
+ break;
+ case TASK_ZOMBIE:
+ cp = "zombie";
+ break;
+ case TASK_STOPPED:
+ cp = "stopped";
+ break;
+ case TASK_SWAPPING:
+ cp = "swapping";
+ break;
+ default:
+ cp = "unknown state";
+ break;
+ }
+ runint = p->utime + p->stime;
+ runfrac = ((runint % HZ) * 100) / HZ;
+ runint /= HZ;
+ if (runint < 60)
+ sprintf(runstr, "%d.%02d", runint, runfrac);
+ else if (runint < 60*60)
+ sprintf(runstr, "%d:%02d.%02d", runint / 60, runint % 60,
+ runfrac);
+ else
+ sprintf(runstr, "%d:%02d:%02d.%02d", runint / (60*60),
+ (runint % (60*60)) / 60, runint % 60, runfrac);
+
+ vsize = 0;
+ pc = 0;
+ if (p->kernel_stack_page) {
+ vsize = VSIZE(p, p->kernel_stack_page) / 1024;
+ pc = KSTK_EIP(p->kernel_stack_page);
+ }
+
+ sprintf(str, "pid %d (%s) cpu %s mem %d/%d pgft %d pc %x %s\r\n",
+ p->pid,
+ p->comm,
+ runstr,
+ p->rss * 4,
+ vsize,
+ p->maj_flt + p->min_flt,
+ pc,
+ cp);
+ cp = str;
+
+ store: /*
+ * Here to store a string into a terminal output buffer if it
+ * will fit. This is not quite right, since newlines aren't
+ * handled properly. This should really call a new routine in
+ * tty_io which would do this correctly.
+ */
+ if (strlen(cp) > LEFT(&tty->write_q))
+ return;
+ while (*cp)
+ put_tty_queue(*cp++, &tty->write_q);
+ TTY_WRITE_FLUSH(tty);
+ }
+

static struct file_operations proc_array_operations = {
NULL, /* array_lseek */
diff --context --recursive linux-0.99.5.O/fs/select.c linux-0.99.5.N/fs/select.c
*** linux-0.99.5.O/fs/select.c Fri Jan 1 21:46:31 1993
--- linux-0.99.5.N/fs/select.c Tue Feb 23 19:10:41 1993
***************
*** 109,114 ****
--- 109,115 ----
wait = &wait_table;
repeat:
current->state = TASK_INTERRUPTIBLE;
+ current->waitstr = "select wait";
for (i = 0 ; i < n ; i++) {
if (FD_ISSET(i,in) && check(SEL_IN,wait,current->filp[i])) {
FD_SET(i, res_in);
diff --context --recursive linux-0.99.5.O/fs/super.c linux-0.99.5.N/fs/super.c
*** linux-0.99.5.O/fs/super.c Thu Jan 21 20:14:08 1993
--- linux-0.99.5.N/fs/super.c Tue Feb 23 19:10:05 1993
***************
*** 52,57 ****
--- 52,58 ----
add_wait_queue(&sb->s_wait, &wait);
repeat:
current->state = TASK_UNINTERRUPTIBLE;
+ current->waitstr = "superblock wait";
if (sb->s_lock) {
schedule();
goto repeat;
diff --context --recursive linux-0.99.5.O/include/linux/sched.h linux-0.99.5.N/include/linux/sched.h
*** linux-0.99.5.O/include/linux/sched.h Tue Feb 9 20:07:52 1993
--- linux-0.99.5.N/include/linux/sched.h Tue Feb 23 19:04:21 1993
***************
*** 159,164 ****
--- 159,166 ----
unsigned long start_code,end_code,end_data,brk,start_stack;
unsigned long arg_start, arg_end, env_start, env_end;
long pid,pgrp,session,leader;
+ unsigned long runorder;
+ char *waitstr;
int groups[NGROUPS];
/*
* pointers to (original) parent process, youngest child, younger sibling,
***************
*** 226,231 ****
--- 228,235 ----
/* ec,brk... */ 0,0,0,0,0,0,0,0, \
/* argv.. */ 0,0,0,0, \
/* pid etc.. */ 0,0,0,0, \
+ /* runorder */ 0, \
+ /* wait str */ NULL, \
/* suppl grps*/ {NOGROUP,}, \
/* proc links*/ &init_task,&init_task,NULL,NULL,NULL, \
/* uid etc */ 0,0,0,0,0,0, \
diff --context --recursive linux-0.99.5.O/include/linux/tty.h linux-0.99.5.N/include/linux/tty.h
*** linux-0.99.5.O/include/linux/tty.h Tue Feb 9 20:07:52 1993
--- linux-0.99.5.N/include/linux/tty.h Thu Feb 25 08:49:28 1993
***************
*** 351,354 ****
--- 351,358 ----
extern int vt_ioctl(struct tty_struct *tty, struct file * file,
unsigned int cmd, unsigned int arg);

+ /* fs/proc/array.c */
+
+ extern void show_proc_status(struct tty_struct *tty);
+
#endif
diff --context --recursive linux-0.99.5.O/kernel/blk_drv/ll_rw_blk.c linux-0.99.5.N/kernel/blk_drv/ll_rw_blk.c
*** linux-0.99.5.O/kernel/blk_drv/ll_rw_blk.c Sat Dec 12 01:05:32 1992
--- linux-0.99.5.N/kernel/blk_drv/ll_rw_blk.c Tue Feb 23 19:35:26 1993
***************
*** 196,201 ****
--- 196,202 ----
unlock_buffer(bh);
return;
}
+ current->waitstr = "request wait";
sleep_on(&wait_for_request);
sti();
goto repeat;
***************
*** 239,244 ****
--- 240,246 ----
if (req->dev<0)
break;
if (req < request) {
+ current->waitstr = "request wait";
sleep_on(&wait_for_request);
goto repeat;
}
***************
*** 369,374 ****
--- 371,377 ----
req->bh = NULL;
req->next = NULL;
current->state = TASK_UNINTERRUPTIBLE;
+ current->waitstr = (rw == READ) ? "swap read" : "swap write";
add_request(major+blk_dev,req);
schedule();
}
diff --context --recursive linux-0.99.5.O/kernel/chr_drv/keyboard.c linux-0.99.5.N/kernel/chr_drv/keyboard.c
*** linux-0.99.5.O/kernel/chr_drv/keyboard.c Wed Jan 13 20:26:21 1993
--- linux-0.99.5.N/kernel/chr_drv/keyboard.c Thu Feb 25 08:50:10 1993
***************
*** 284,289 ****
--- 284,296 ----
chg_vc_kbd_flag(kbd,VC_SCROLLOCK);
}

+ static void procstat(int sc)
+ {
+ #if CONFIG_PROC_FS
+ show_proc_status(TTY_TABLE(0));
+ #endif
+ }
+
static void num(int sc)
{
if (vc_kbd_flag(kbd,VC_APPLIC))
***************
*** 1417,1423 ****
cursor,cursor,minus,cursor, /* 48-4B up pgup - left */
cursor,cursor,plus,cursor, /* 4C-4F n5 right + end */
cursor,cursor,cursor,cursor, /* 50-53 dn pgdn ins del */
! none,none,do_self,func, /* 54-57 sysreq ? < f11 */
func,none,none,none, /* 58-5B f12 ? ? ? */
none,none,none,none, /* 5C-5F ? ? ? ? */
none,none,none,none, /* 60-63 ? ? ? ? */
--- 1424,1430 ----
cursor,cursor,minus,cursor, /* 48-4B up pgup - left */
cursor,cursor,plus,cursor, /* 4C-4F n5 right + end */
cursor,cursor,cursor,cursor, /* 50-53 dn pgdn ins del */
! procstat,none,do_self,func, /* 54-57 sysreq ? < f11 */
func,none,none,none, /* 58-5B f12 ? ? ? */
none,none,none,none, /* 5C-5F ? ? ? ? */
none,none,none,none, /* 60-63 ? ? ? ? */
diff --context --recursive linux-0.99.5.O/kernel/chr_drv/tty_io.c linux-0.99.5.N/kernel/chr_drv/tty_io.c
*** linux-0.99.5.O/kernel/chr_drv/tty_io.c Tue Feb 9 20:08:00 1993
--- linux-0.99.5.N/kernel/chr_drv/tty_io.c Thu Feb 25 08:49:59 1993
***************
*** 543,548 ****
--- 543,562 ----
continue;
}
}
+ /*
+ * The process status character should really have its
+ * own definition, but this requires changing many user
+ * programs. As a partial solution, tie it to the quit
+ * character, so if a program disables quit, they also
+ * disable ^T. Programs that disable quit probably want
+ * to disable all the other special characters anyway.
+ */
+ #if CONFIG_PROC_FS
+ if ((c == 'T'-'@') && ((QUIT_CHAR(tty) != __DISABLED_CHAR))) {
+ show_proc_status(tty);
+ continue;
+ }
+ #endif
if (c==10 || (EOF_CHAR(tty) != __DISABLED_CHAR &&
c==EOF_CHAR(tty)))
tty->secondary.data++;
***************
*** 683,688 ****
--- 697,703 ----
if (hung_up(file))
break;
current->state = TASK_INTERRUPTIBLE;
+ current->waitstr = "tty input";
if (EMPTY(&tty->secondary))
schedule();
current->state = TASK_RUNNING;
***************
*** 717,722 ****
--- 732,738 ----
add_wait_queue(&tty->secondary.proc_list, &wait);
while (1) {
current->state = TASK_INTERRUPTIBLE;
+ current->waitstr = "tty input";
if (available_canon_input(tty))
break;
if (current->signal & ~current->blocked)
***************
*** 764,769 ****
--- 780,786 ----
break;
}
current->state = TASK_INTERRUPTIBLE;
+ current->waitstr = "tty output";
if (FULL(&tty->write_q)) {
TTY_WRITE_FLUSH(tty);
if (FULL(&tty->write_q))
diff --context --recursive linux-0.99.5.O/kernel/exit.c linux-0.99.5.N/kernel/exit.c
*** linux-0.99.5.O/kernel/exit.c Sun Dec 13 13:17:11 1992
--- linux-0.99.5.N/kernel/exit.c Wed Feb 24 07:18:06 1993
***************
*** 508,513 ****
--- 508,514 ----
if (options & WNOHANG)
return 0;
current->state=TASK_INTERRUPTIBLE;
+ current->waitstr = "proc wait";
oldblocked = current->blocked;
current->blocked &= ~(1<<(SIGCHLD-1));
schedule();
diff --context --recursive linux-0.99.5.O/kernel/sched.c linux-0.99.5.N/kernel/sched.c
*** linux-0.99.5.O/kernel/sched.c Tue Feb 9 20:08:14 1993
--- linux-0.99.5.N/kernel/sched.c Wed Feb 24 05:59:15 1993
***************
*** 47,52 ****
--- 47,53 ----

static unsigned long init_kernel_stack[1024];
static struct task_struct init_task = INIT_TASK;
+ static unsigned long runcounter = 0;

unsigned long volatile jiffies=0;
unsigned long startup_time=0;
***************
*** 136,141 ****
--- 137,146 ----
(*p)->priority;
}
sti();
+ if (next) {
+ task[next]->runorder = ++runcounter;
+ task[next]->waitstr = NULL;
+ }
switch_to(next);
}

***************
*** 150,155 ****
--- 155,161 ----
if (sa->sa_handler == SIG_IGN)
current->blocked |= mask;
current->state = TASK_INTERRUPTIBLE;
+ current->waitstr = "paused";
schedule();
current->blocked = old_blocked;
return -EINTR;

David I. Bell
db...@pdact.pd.necisa.oz.au

Ben Cox

unread,
Feb 25, 1993, 1:16:10 PM2/25/93
to
db...@pdact.pd.necisa.oz.au (David I. Bell) writes:

>Here are patches for 0.99.5 to implement a ^T feature for linux. This
>feature gives you an instant status report about the most recently running

>process on your terminal. [...]

This patch really doesn't seem to have any business being in the
kernel; shouldn't it be a feature of the shell?

--
Ben Cox
th...@uiuc.edu

Warner Losh

unread,
Feb 25, 1993, 4:02:21 PM2/25/93
to
In article <ben.730664170@ipoint> th...@uiuc.edu (Ben Cox) writes:
>This patch really doesn't seem to have any business being in the
>kernel; shouldn't it be a feature of the shell?

There need to be some sort of hooks in the kernel to allow it to be
implemented in the shell. Otherwise, the shell will have no way to
know when the "status" key has been pressed.

I haven't seen the patch yet, so I don't know if it adds too much to
the kernel or not.

Warner
--
Warner Losh i...@boulder.parcplace.COM ParcPlace Boulder
I've almost finished my brute force solution to subtlety.

John F Carr

unread,
Feb 26, 1993, 3:02:08 AM2/26/93
to
In article <ben.730664170@ipoint> th...@uiuc.edu (Ben Cox) writes:

>This patch really doesn't seem to have any business being in the
>kernel; shouldn't it be a feature of the shell?

No, this patch does belong in the kernel. The shell doesn't have enough
information. The shell may not even be running. One reason to press ^T is
to find out if a process is hung.

BSD 4.4- and some versions of OSF/1 do even better: they send the process a
signal when the user presses ^T, so it can print status information.

--
John Carr (j...@athena.mit.edu)

Kevin Brown

unread,
Feb 26, 1993, 3:17:52 AM2/26/93
to
In article <ben.730664170@ipoint> th...@uiuc.edu (Ben Cox) writes:

Ideally, yes. However...

In order to get the semantics you want, you have to be able to type ctrl-t
when you have a process in the foreground that was started by the shell.
Unfortunately, this implies that the shell is waiting for the process to
complete, and the only way to get the shell's attention is to cause a
signal to be sent. That can only happen from within the kernel, and thus
a kernel patch is required.

That *does* suggest that a more appropriate way to do this would be to
define an extra key which sends a new type of signal to the controlling
process of the terminal that sent the key, and arrange for the default
behavior of the signal to be SIG_IGN (so that hitting the key doesn't
kill your process if it's not explicitly listening for it).

Having experienced this particular feature of VMS, I can definitely
state that it's a nice thing to have. But I don't know if it's worth
messing with the internals of the kernel in order to get it. My personal
opinion is that this probably doesn't belong in the main distribution.
Keep it a patch that can be applied to whatever the latest kernel is.

>Ben Cox
>th...@uiuc.edu


--
Kevin Brown ke...@nuchat.sccsi.com
This is your .signature virus: < begin 644 .signature (9V]T8VAA(0K0z end >
This is your .signature virus on drugs: <>
Any questions?

william E Davidsen

unread,
Feb 26, 1993, 3:40:30 PM2/26/93
to
In article <1mkiq0...@senator-bedfellow.MIT.EDU>, j...@athena.mit.edu (John F Carr) writes:

| No, this patch does belong in the kernel. The shell doesn't have enough
| information. The shell may not even be running. One reason to press ^T is
| to find out if a process is hung.
|
| BSD 4.4- and some versions of OSF/1 do even better: they send the process a
| signal when the user presses ^T, so it can print status information.

I suppose you could argue that if you trap the process and it
*doesn't* come back with status you can assume it's hung, but I'd rather
have the kernel tell me about the process, since then if I don't get
status I know the system has gone away.

--
bill davidsen, GE Corp. R&D Center; Box 8; Schenectady NY 12345
Windows NT is a *great* program!
It's everything CP/M should have been all along.

Charles Hedrick

unread,
Feb 26, 1993, 11:02:39 PM2/26/93
to
th...@uiuc.edu (Ben Cox) writes:

This is a feature that is pretty commonly added to Unix kernels, at
least at universities. We use it on our Suns. 386BSD seems to have
it. I think some vendors do as well. I agree that it's more elegant
to put it in the shell, but there's some question whether it's worth
being incompatible with other implementations. Some software already
supports this. It's probably better to support at least the standard
way for disabling it. (The character is offset VSTATUS in c_cc.
Arrrggggg... SVr4 reserves space for it in the c_cc array. Linux
seems not to have done so. This could make for some excitement.)
It's not good enough for the shell to respond to ^T as the shell reads
it. One of the major uses is when you're trying a program and getting
no reaction. ^T lets you see what is going on. In this case the
shell isn't active. If you're going to do it in the shell, you'd want
to do it like TOPS-20: implement an ioctl that lets you attach a
control character to a signal. So ^T would generate some signal, and
the shell's trap handler for that signal would print the message.

I would urge Linus to take this patch (assuming it is a reasonable
implementation -- I haven't looked at it yet). ^T is the primary
thing I miss on Linux at the moment.

Joel M. Hoffman

unread,
Feb 27, 1993, 11:30:45 AM2/27/93
to
In article <Feb.26.23.02...@geneva.rutgers.edu> hed...@geneva.rutgers.edu (Charles Hedrick) writes:
[re ^T process status feature]

>I would urge Linus to take this patch (assuming it is a reasonable
>implementation -- I haven't looked at it yet). ^T is the primary
>thing I miss on Linux at the moment.

What happens when a user program uses ^T (e.g., the shell, emacs,
nethack, etc.)? Who sees the ^T, the kernel or the app? If the app.,
a broken app. will kill the feature, and if the kernel, you'll break
common apps. What I would recommend is using some >unused< key for
process status. (Alt-PgUp, eg. -- I've never used that one before.)

-Joel

Rick Sladkey

unread,
Feb 27, 1993, 1:24:46 PM2/27/93
to
>>>>> On 27 Feb 93 04:02:39 GMT,
>>>>> hed...@geneva.rutgers.edu (Charles Hedrick) said:

Charles> (The character is offset VSTATUS in c_cc. Arrrggggg... SVr4
Charles> reserves space for it in the c_cc array. Linux seems not to
Charles> have done so. This could make for some excitement.)

No excitement necessary. There is room for two more characters in the
c_cc array without changing the size of a termios structure.

This program demonstrates that NCCS can be changed from 17 to 19
without breaking anything:

$ cat tiosize.c
#include <stdio.h>
#include <termios.h>

main(void)
{
printf("sizeof (struct termios) = %d, end = %d\n",
sizeof (struct termios),
(int) &((struct termios *) NULL)->c_cc[NCCS]);
exit(0);
}
$ cc tiosize.c
$ a.out
sizeof (struct termios) = 36, end = 34
$

Warner Losh

unread,
Feb 28, 1993, 2:11:36 AM2/28/93
to
In article <1993Feb27.1...@wam.umd.edu> jo...@wam.umd.edu (Joel

M. Hoffman) writes:
>What happens when a user program uses ^T (e.g., the shell, emacs,
>nethack, etc.)? Who sees the ^T, the kernel or the app? If the app.,
>a broken app. will kill the feature, and if the kernel, you'll break
>common apps. What I would recommend is using some >unused< key for
>process status. (Alt-PgUp, eg. -- I've never used that one before.)

After looking at the patch and some commentary that I got from the
author, it appears that in raw mode this feature is disabled, so emacs
should work OK. It also prints the information on SysReq (or
something like that). Keep in mind that there is no ASCII character
that corresponds to many of the keys on they keyboard, so it has to be
something that both local and remote users can type. It also has to
be something that will work inside of X windows. ^T seems reasonable
enough to me, but I'd like to see that under user control somehow.

This is also how it worked on TOPS-20, VMS, and RSTS/E.

Kevin Sanders

unread,
Mar 1, 1993, 7:30:43 PM3/1/93
to
>In article <ben.730664170@ipoint> th...@uiuc.edu (Ben Cox) writes:
>>This patch really doesn't seem to have any business being in the
>>kernel; shouldn't it be a feature of the shell?

Should it be a feature at all?

I really don't understand what this feature buys you in light of the
existence of VC's (which the older systems did not have), and X windows
(same thing). How bad can it be to just switch VC's to the continuously-
running "top" display you've got, or just to another shell to type "ps"?

It just doesn't seem worth changing the kernel for something marginally
better than what we already have.

--
Kevin Sanders, KN6FQ NCR Torrey Pines
kevin....@torreypinesca.ncr.com (619) 597-3602
kevin%bea...@cyber.net

Charles Hedrick

unread,
Mar 1, 1993, 10:57:58 PM3/1/93
to
jo...@wam.umd.edu (Joel M. Hoffman) writes:

>What happens when a user program uses ^T (e.g., the shell, emacs,
>nethack, etc.)? Who sees the ^T, the kernel or the app? If the app.,
>a broken app. will kill the feature, and if the kernel, you'll break
>common apps. What I would recommend is using some >unused< key for
>process status. (Alt-PgUp, eg. -- I've never used that one before.)

I'll speak for the implementation we're currently using under SunOS,
which I believe is typical. The kernel processes ^T. The user can
pick his own key, e.g. "stty status '^t'". Hardwiring Alt-PgUp won't
do, because that won't work for dumb terminals, telnet, xterm windows,
etc. The key is defined in c_cc[VSTATUS] in termios. Processing
occurs only for canonical input. Typically the programs that wouldn't
want it disable ICANON. (At least on my Suns, emacs, mm, vi, and top
all disable ICANON. I don't see anything that would want to disable
^T that doesn't already disable ICANON.) You can also disable it
explicitly be setting c_cc[VSTATUS] to 255. The main compatibility
problem is that c_cc in Linux doesn't have space for it. In SunOS,
VSTATUS is defined in termios.h, though the feature isn't implemented.
In SVr4, VSTATUS isn't defined, but 4 extra bytes are provided at the
end of c_cc, which leaves space for it. For Linux, we'd have to
extend c_cc, and provide a new version of the termios system call,
which supports the full-size c_cc. I would recommend following the
SVr4 example and adding extra entries.

John F Carr

unread,
Mar 2, 1993, 2:31:30 PM3/2/93
to
In article <1993Mar2.0...@TorreyPinesCA.ncr.com>
ke...@TorreyPinesCA.ncr.com (Kevin Sanders) writes:

>I really don't understand what this feature buys you in light of the
>existence of VC's (which the older systems did not have), and X windows
>(same thing).

I use the X Window System and still find ^T a valuable feature.
I usually set my shell prompt to include the working directory,
even though I could type "pwd". Similarly, ^T is easier than
running the several commands needed to get the same information.


--
John Carr (j...@athena.mit.edu)

Warner Losh

unread,
Mar 2, 1993, 2:11:46 PM3/2/93
to
>I really don't understand what this feature buys you in light of the
>existence of VC's (which the older systems did not have), and X windows
>(same thing). How bad can it be to just switch VC's to the continuously-
>running "top" display you've got, or just to another shell to type "ps"?

Keep in mind that you can use a linux box from places other than the
console. If I'm telneted into a linux box, for exanpel, then I cannot
change to another X window, or try another VC to get this information.
I want to know if the system is hung or not. If I'm dialed into my
system from a remote site, then I cannot switch either. It seems like
a rather high overhead to have to log in someplace else, just to see
if how my process is doing.[*]

It is a reasonable feature to have, even in light of these other
features.

Warner

[*] I do know about the various muxing program that are available.
Last time I used them they were all too painful to use on a regular
basis.

Theodore Ts'o

unread,
Mar 2, 1993, 11:56:46 PM3/2/93
to
From: hed...@geneva.rutgers.edu (Charles Hedrick)
Date: 2 Mar 93 03:57:58 GMT

The main compatibility
problem is that c_cc in Linux doesn't have space for it. In SunOS,
VSTATUS is defined in termios.h, though the feature isn't implemented.
In SVr4, VSTATUS isn't defined, but 4 extra bytes are provided at the
end of c_cc, which leaves space for it. For Linux, we'd have to
extend c_cc, and provide a new version of the termios system call,
which supports the full-size c_cc.

Actually, because of how GCC aligns variables, it should be safe to bump
NCCS from 17 to 19 without causing any compatibility problems.

- Ted

0 new messages