Linux Archive

Linux Archive (http://www.linux-archive.org/)
-   Debian User (http://www.linux-archive.org/debian-user/)
-   -   Does anyone understand terminal job control? (http://www.linux-archive.org/debian-user/241974-does-anyone-understand-terminal-job-control.html)

Daniel Burrows 02-07-2009 11:58 PM

Does anyone understand terminal job control?
 
Hello list,

I've been banging my head on this one for a while.

I have a need to write some code that can manage job control on a
terminal. More specifically, I need to run a single process and stuff
it into the background at will, so that it gets suspended when it tries
to read from the terminal. So, there's a "controller" process and
a "subprocess" process.

controller ----------> subprocess
manages

The man-pages and glibc info documentation make this look simple:
disable TOSTOP if it's enabled via tc[gs]etattr(), then start the
subprocess in a new process group (using setpgid); once it's going,
you can put it in the "foreground" or "background" by calling
tcsetpgrp() to set the terminal's foreground process group. If you
set it to the subprocess, the subprocess will be the foreground group;
otherwise, the controller will be the foreground group. Whenever the
subprocess is in the background, it will be sent SIGTTIN if it tries to
read from the terminal.

I have everything working -- except for the very last sentence of
that last paragraph. I can see my processes being put into the right
process group, and I can see them going into the foreground and the
background, e.g.:

STAT CMD PID PGID TPGID PPID SID
Ss+ ./src/aptitude 26989 26989 26989 26980 26989
S ./src/aptitude 26991 26991 26989 26989 26989
S /bin/sh -c /usr/sbin/dpkg-p 27027 26991 26989 26991 26989
S /usr/bin/perl -w /usr/sbin/ 27028 26991 26989 27027 26989
Z [dpkg-preconfigu] <defunct> 27034 26991 26989 27028 26989
S /bin/sh -e /tmp/lynx-cur.co 27039 26991 26989 27028 26989
S whiptail --backtitle Packag 27043 26991 26989 27028 26989

and then if I move the background process into the foreground:

STAT CMD PID PGID TPGID PPID SID
Ss ./src/aptitude 26989 26989 26991 26980 26989
S+ ./src/aptitude 26991 26991 26991 26989 26989
S+ /bin/sh -c /usr/sbin/dpkg-p 27027 26991 26991 26991 26989
S+ /usr/bin/perl -w /usr/sbin/ 27028 26991 26991 27027 26989
Z+ [dpkg-preconfigu] <defunct> 27034 26991 26991 27028 26989
S+ /bin/sh -e /tmp/lynx-cur.co 27039 26991 26991 27028 26989
S+ whiptail --backtitle Packag 27043 26991 26991 27028 26989

Note that the background process is not suspended. If I manually
suspend the process group with "kill -TTIN -26991", it stops as
expected:

TAT CMD PID PGID TPGID PPID SID
Ss ./src/aptitude 26989 26989 26991 26980 26989
T+ ./src/aptitude 26991 26991 26991 26989 26989
T+ /bin/sh -c /usr/sbin/dpkg-p 27027 26991 26991 26991 26989
T+ /usr/bin/perl -w /usr/sbin/ 27028 26991 26991 27027 26989
Z+ [dpkg-preconfigu] <defunct> 27034 26991 26991 27028 26989
T+ /bin/sh -e /tmp/lynx-cur.co 27039 26991 26991 27028 26989
T+ whiptail --backtitle Packag 27043 26991 26991 27028 26989

So the signal isn't being blocked or ignored. I can also run
programs in the shell (e.g., "links &") and watch them
auto-suspend, but the same thing doesn't happen when I start them
directly under my controller process. It's not even that they're
starting as foreground processes: I can start them without access to
the controlling terminal, and they never see a SIGTTIN.



Does anyone have a clue what's going on? Hopefully it's as simple
as a flag I have to set somewhere...

Oh, and for extra fun, this is all happening inside a VTE terminal
widget. That shouldn't make a difference (after all, it's what
gnome-terminal uses, and TTIN behaved as expected when I tested it
there), but who knows, it might be relevant.

Thanks,
Daniel


--
To UNSUBSCRIBE, email to debian-user-REQUEST@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org

"Boyd Stephen Smith Jr." 02-08-2009 03:43 AM

Does anyone understand terminal job control?
 
On Saturday 07 February 2009 18:58:13 Daniel Burrows wrote:
> I've been banging my head on this one for a while.

The source for /bin/dash and /bin/bash are available. You might should be
able to peruse them and find the correct way to suspend/resume/detach/etc.
processes.
--
Boyd Stephen Smith Jr. ,= ,-_-. =.
bss@iguanasuicide.net ((_/)o o(\_))
ICQ: 514984 YM/AIM: DaTwinkDaddy `-'(. .)`-'
http://iguanasuicide.net/ \_/

"Douglas A. Tutty" 02-08-2009 03:59 AM

Does anyone understand terminal job control?
 
On Sat, Feb 07, 2009 at 10:43:11PM -0600, Boyd Stephen Smith Jr. wrote:
> On Saturday 07 February 2009 18:58:13 Daniel Burrows wrote:
> > I've been banging my head on this one for a while.
>
> The source for /bin/dash and /bin/bash are available. You might should be
> able to peruse them and find the correct way to suspend/resume/detach/etc.
> processes.

Would the screen program (or its sources) be of any help?

Doug


--
To UNSUBSCRIBE, email to debian-user-REQUEST@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org

"Boyd Stephen Smith Jr." 02-08-2009 04:44 AM

Does anyone understand terminal job control?
 
On Saturday 07 February 2009 22:59:25 Douglas A. Tutty wrote:
> On Sat, Feb 07, 2009 at 10:43:11PM -0600, Boyd Stephen Smith Jr. wrote:
> > On Saturday 07 February 2009 18:58:13 Daniel Burrows wrote:
> > > I've been banging my head on this one for a while.
> >
> > The source for /bin/dash and /bin/bash are available. You might should
> > be able to peruse them and find the correct way to
> > suspend/resume/detach/etc. processes.
>
> Would the screen program (or its sources) be of any help?

My first guess would be no. Screen does not multiplex the terminal the same
way job control does. In particular, processes in a screen window that is no
active that attempt to write to the terminal are *not* suspended (via signal
or otherwise). Instead, each screen window is its own "pseudo"-tty, so the
processes can write to them while one of them is reflected in the tty attached
to screen.

(I could be wrong though, I'm not a expert in the source of any of these
programs.)
--
Boyd Stephen Smith Jr. ,= ,-_-. =.
bss@iguanasuicide.net ((_/)o o(\_))
ICQ: 514984 YM/AIM: DaTwinkDaddy `-'(. .)`-'
http://iguanasuicide.net/ \_/

Adrian Levi 02-08-2009 06:52 AM

Does anyone understand terminal job control?
 
2009/2/8 Daniel Burrows <dburrows@debian.org>:
> Hello list,
>
> I've been banging my head on this one for a while.
>
> I have a need to write some code that can manage job control on a
> terminal. More specifically, I need to run a single process and stuff
> it into the background at will, so that it gets suspended when it tries
> to read from the terminal. So, there's a "controller" process and
> a "subprocess" process.
>
> controller ----------> subprocess
> manages

You cant send the equivalent of ^z then fg to resume?
AFAIK the process will be suspended until you type bg to run the
process in the background or fg to bring it back into the foreground.

Hope this helps you.

Adrian

--
24x7x365 != 24x7x52 Stupid or bad maths?
<erno> hm. I've lost a machine.. literally _lost_. it responds to
ping, it works completely, I just can't figure out where in my
apartment it is.


--
To UNSUBSCRIBE, email to debian-user-REQUEST@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org

"Douglas A. Tutty" 02-08-2009 11:58 AM

Does anyone understand terminal job control?
 
On Sun, Feb 08, 2009 at 05:52:34PM +1000, Adrian Levi wrote:
> 2009/2/8 Daniel Burrows <dburrows@debian.org>:
> > Hello list,
> >
> > I've been banging my head on this one for a while.
> >
> > I have a need to write some code that can manage job control on a
> > terminal. More specifically, I need to run a single process and stuff
> > it into the background at will, so that it gets suspended when it tries
> > to read from the terminal. So, there's a "controller" process and
> > a "subprocess" process.
> >
> > controller ----------> subprocess
> > manages

Is the single process a black box or are you writing it too? If its not
a black box, can't its reads from the terminal just sit and wait for
input (or test a semiphor before doing anything with the terminal)?

If it is a black box, what happens if it tries to read from std-in if
std-in doesn't have anything? Perhaps your controller program will have
to be a filter between the process and the terminal: pipe its std-in an
std-out to the controller process and the controller process issue the
appropriate shell start/stop commands as necessary while leaving the
process in the background the whole time. If this model works, then
this controller process can manage any number of daughter processes,
each using e.g. a pair of named pipes for std-in and std-out.

Just an early-morning thought.

Doug.


--
To UNSUBSCRIBE, email to debian-user-REQUEST@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org

Mirko Parthey 02-08-2009 09:15 PM

Does anyone understand terminal job control?
 
On Sat, Feb 07, 2009 at 04:58:13PM -0800, Daniel Burrows wrote:
> directly under my controller process. It's not even that they're
> starting as foreground processes: I can start them without access to
> the controlling terminal, and they never see a SIGTTIN.

What do you mean by: "without access to the controlling terminal"?
Is the controlling terminal actually connected to the stdin of your
subprocess in the normal case (check in /proc to be sure)?

The libc info also has example code for implementing a shell with job
control, but I haven't looked at it closely yet.

Regards,
Mirko


--
To UNSUBSCRIBE, email to debian-user-REQUEST@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org

Daniel Burrows 02-09-2009 03:14 AM

Does anyone understand terminal job control?
 
On Sun, Feb 08, 2009 at 11:15:46PM +0100, Mirko Parthey <mirko.parthey@informatik.tu-chemnitz.de> was heard to say:
> On Sat, Feb 07, 2009 at 04:58:13PM -0800, Daniel Burrows wrote:
> > directly under my controller process. It's not even that they're
> > starting as foreground processes: I can start them without access to
> > the controlling terminal, and they never see a SIGTTIN.
>
> What do you mean by: "without access to the controlling terminal"?
> Is the controlling terminal actually connected to the stdin of your
> subprocess in the normal case (check in /proc to be sure)?

I was being sloppy :) -- I meant that the terminal has been "taken
away" via tcsetpgrp().

> The libc info also has example code for implementing a shell with job
> control, but I haven't looked at it closely yet.

Yeah, that's basically what I was basing my ideas on.

The fundamental issue seems to be that the subprocess has to actually
issue a read() system call in order to be stopped. For normal shells
this isn't a problem: if the subprocess is blocked in select() that's
OK (it's not actually messing with the terminal stream), and as soon as
the user types something, it'll wake up, try to read(), and get
suspended. I'm just (ab)using this in an unusual way to detect when a
background process is trying to read from a hidden terminal.
Unfortunately, there's nothing in this scenario that would kick it out
of the select() and into read(), so I can't detect the reader.

Daniel


--
To UNSUBSCRIBE, email to debian-user-REQUEST@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org

Daniel Burrows 02-09-2009 03:22 AM

Does anyone understand terminal job control?
 
On Sun, Feb 08, 2009 at 05:52:34PM +1000, Adrian Levi <adrian.levi@gmail.com> was heard to say:
> 2009/2/8 Daniel Burrows <dburrows@debian.org>:
> > Hello list,
> >
> > I've been banging my head on this one for a while.
> >
> > I have a need to write some code that can manage job control on a
> > terminal. More specifically, I need to run a single process and stuff
> > it into the background at will, so that it gets suspended when it tries
> > to read from the terminal. So, there's a "controller" process and
> > a "subprocess" process.
> >
> > controller ----------> subprocess
> > manages
>
> You cant send the equivalent of ^z then fg to resume?
> AFAIK the process will be suspended until you type bg to run the
> process in the background or fg to bring it back into the foreground.

Well, the issue is that I don't know when to sent the SIGSTOP (that
is, ^Z). :-) I'm trying to do it only when the process wants to read
from the terminal, but allow it to run unmolested otherwise.

Based on some additional tests I ran, it looks like the mechanism
that triggers SIGTTIN only activates when the subprocess actually
invokes the read() system call -- the one I was testing with blocks in
select() until input is available, and that doesn't seem to trigger the
TTIN. (if I type a character while it's "in the background", that does
cause it to suspend)

The use case here is basically that I have a hidden terminal with a
long-running batch process that occasionally prompts for user input,
and I want to detect when it's waiting so I can alert the user. I'm
trying to find a way to get it to emit some sort of signal / event that
the parent process can catch, and I latched onto SIGTTIN as a route to
that. It's looking to me like it might not be possible to implement
what I want through the job control mechanism, although I found some
intriguing notes about VDSUSP yesterday that I haven't followed up on.

Daniel


--
To UNSUBSCRIBE, email to debian-user-REQUEST@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org

Daniel Burrows 02-09-2009 03:27 AM

Does anyone understand terminal job control?
 
On Sun, Feb 08, 2009 at 07:58:51AM -0500, "Douglas A. Tutty" <dtutty@vianet.ca> was heard to say:
> On Sun, Feb 08, 2009 at 05:52:34PM +1000, Adrian Levi wrote:
> > 2009/2/8 Daniel Burrows <dburrows@debian.org>:
> > > Hello list,
> > >
> > > I've been banging my head on this one for a while.
> > >
> > > I have a need to write some code that can manage job control on a
> > > terminal. More specifically, I need to run a single process and stuff
> > > it into the background at will, so that it gets suspended when it tries
> > > to read from the terminal. So, there's a "controller" process and
> > > a "subprocess" process.
> > >
> > > controller ----------> subprocess
> > > manages
>
> Is the single process a black box or are you writing it too? If its not
> a black box, can't its reads from the terminal just sit and wait for
> input (or test a semiphor before doing anything with the terminal)?

The part that reads from the terminal is a black box -- it could be
anything invoked by a dpkg maintainer script.

> If it is a black box, what happens if it tries to read from std-in if
> std-in doesn't have anything?

After I sent the mail, I figured out that if it ever *actually* tries
to read from stdin, it gets stopped. The problem is that the program
I was testing with apparently blocks in select() instead of reading
outright, and select() doesn't trigger SIGTTIN; it has to issue a read().

> Perhaps your controller program will have
> to be a filter between the process and the terminal: pipe its std-in an
> std-out to the controller process and the controller process issue the
> appropriate shell start/stop commands as necessary while leaving the
> process in the background the whole time.

I thought about this option, but the problem is detecting when the
subprocess is trying to read (but I don't have anything to give it).
One interesting idea I got from the libc manual (but have yet to follow
up on) is to inject a VDSUSP character into the stream -- apparently
this will suspend the process, but only when the character is actually
read. I vaguely recall having some reason to think it might not work,
but it's worth at least trying. (as it happens, since I control the
terminal, I don't need a man in the middle to do this (I think) -- I
can just ask the terminal to send the character)

Daniel


--
To UNSUBSCRIBE, email to debian-user-REQUEST@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org


All times are GMT. The time now is 04:41 PM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.