linux-assembly.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Philip Jacob Smith <pj@evobsyniva.com>
To: linux-assembly@vger.kernel.org
Subject: Re: Orphaned Processes and TCSETSW
Date: Sun, 19 Oct 2003 15:50:25 -0400	[thread overview]
Message-ID: <oprxa2qb0ob2epmx@localhost> (raw)
In-Reply-To: <3F92B6E9.BF7360A8@yahoo.co.uk>

> my solution, not at all perfect, but at least providing some last
> resort, is the aequivalent to <stty sane> coded into the final clean-up
> procedure plus, a (sort of) switch by which that part could be
> dis-abled, at runtime.
> at least, it returns the keyboard in an accessible state and, it's
> results are something which can easily be managed w. the standard tools.

I tried a few perl scripts...  (I'm retying these from memory, so if I forget a semicolon and perl won't accept them, forgive me.)

if (fork == 0) {
	sleep 1;
	`stty sane`;
};

For those who don't know perl, this script forks, then if it's the child, it sleeps for a second then executes the command 'stty sane', or if it's the parent, it'll just exit.

This script causes the error.  You'll see stty complain about an I/O error.

So I went back to the softer source and coded it so that when it does the final equivelent of 'stty sane' it first opens /dev/tty4 and does it on the file descriptor there, thinking maybe a new open might clear up the problem, but that didn't work, the error occoured even with the new file handle.

So I went back to perl and tried this:

if (fork == 0) {
	if (fork == 0) {
		if (fork == 0) {
			sleep 1;
			`stty sane`;
		};
	};
} else {
	sleep 4;
};

That's probably more forks than are necissary, but anyway this script works.  If you comment out the 'sleep 4' then it stops working.

This made me think that maybe it was failing because a process was reading from stdin, so I tried this script.

if (fork == 0) {
	if (fork == 0) {
		if (fork == 0) {
			sleep 1;
			`stty sane`;
		};
	};
} else {
	<>;
};
	
In perl, <> will read a line from standard input.

This script had no problems, so it's not reading from stdin that does it.  So then I tried this.

if (fork == 0) {
	if (fork == 0) {
		if (fork == 0) {
			sleep 3;
			`stty sane`;
		};
	};
} else {
	sleep 1;
	`stty raw`;
	sleep 4;
};

This script didn't have any problems either.

So now I'm thinking maybe it's bash, or that readline library it uses.  So I try a few other shells, they all do it too.  Then I take the first script, lengthen it's sleep time to 5 seconds, then after running it I execute 'sleep 10' before it gets around to doing the stty command, so that bash won't be reading the keyboard when it does the stty command.  This still causes the error.  So this makes me think that it's probably not the shell.

So I'm lost at this point.  As best I can tell, the problem occours when you have a parent-child chain like

shell -> process_1 -> process_2 -> process_3 -> process_4 -> process_5

and any process 2 or greater tries to modify terminal settings when process_1 has already exited.
There's no problem if process 3 or greater does the same after process 2 has exited, but rather the whole chain can do whatever it wants so long as process_1 hasn't exited, and once it has, none of them can do anything, regardless of which others have or haven't exited.

Interestingly, if I start another shell by typing 'bash', it now works as if the new bash is 'shell' in the above diagram, even though it's 'process_1'.  So I don't think it's something to do with who opened that particular TTY first.

So I guess that either bash (or the readline libaray) is making a system call after exit to cause this to happen, or when bash starts up it makes one system call to make this happen automatically.

So I tried one of the scripts that fail, but ran it like this:

	./fork_test.pl | sleep 5

This way it works just fine.  So I'm thinking maybe it's bash making a system call.

Doing an strace on bash, I see it make an ioctl 0x5410, which turns out to be TIOCSPGRP.  As best I can tell, this has something to do with changing the process group of the controlling terminal, or something like that.

So I go to console number 4, and type this:

stty raw -echo < /dev/tty1

Then I switch over to console 1, and sure enough, it did just what it was supposed to.

So it seems that it's not that Softer isn't in the process group, but that it was at one time in the process group, and isn't any longer.

So then I make softer call setsid to make it's own process group.  This fixes the problem, but now we have the problem you described before, as bash saves the incorrect settings when gpsmap exits, then softer fixes them, but of course when bash later goes to restore them, they're incorrect again.  All that trouble for something that didn't even work...

I also noticed that if softer is executed from the shell, it's setsid call fails, which I guess means that softer is the process group leader, not the shell.  So I guess once the process group leader is dead, none of it's child processes can change the terminal settings.

Anyway, I guess I could just make gpsmap execute softer with gpsmap on it's command line, so that softer will start gpsmap and the processes will be lined up in the right order.  It's odd how obvious solutions like this completly slip my mind until I've come to realize that the way I wanted to do it is impossible.  The thought didn't cross my mind until I was typing "when bash later goes to restore them..."

Thanks for helping out, I had pretty much given up until I read that you were writing code to try to help.

 - Pj


  reply	other threads:[~2003-10-19 19:50 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-10-17 17:22 correction: Re: Orphaned Processes and TCSETSW] willy meier
2003-10-17 21:37 ` Orphaned Processes and TCSETSW Philip Jacob Smith
2003-10-19 16:08   ` willy meier
2003-10-19 19:50     ` Philip Jacob Smith [this message]
2003-10-20 11:38       ` willy meier
  -- strict thread matches above, loose matches on Subject: below --
2003-10-12 23:22 linuxassembly
2003-10-17 17:18 ` willy meier

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=oprxa2qb0ob2epmx@localhost \
    --to=pj@evobsyniva.com \
    --cc=linux-assembly@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).