Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 26 Sep 1997 11:59:14 +0000 (GMT)
From:      Terry Lambert <tlambert@primenet.com>
To:        mike@smith.net.au (Mike Smith)
Cc:        hackers@FreeBSD.ORG
Subject:   Re: Timeout for sh(1) 'read' ??
Message-ID:  <199709261159.EAA20125@usr09.primenet.com>
In-Reply-To: <199709260748.RAA00456@word.smith.net.au> from "Mike Smith" at Sep 26, 97 05:18:45 pm

next in thread | previous in thread | raw e-mail | index | archive | help
> Hiho folks, a question for the sh(1) studs amongst you :
> 
>  - I want to prompt for input using 'read', and have the read return in
>    some fashion after a timeout.
> 
> I'd like to do this just using sh, and I'm not too fussed about how 
> hairy it is.  Any ideas?
> 
> (If sh has to be modified to achieve this, would it be a useful thing 
> to bring back?)

Write a "timedread" program that returns "TIMEOUT" or "USERDATA xxxxx"
and do "timedread | read x" and look at the front of x?  8-) 8-).

Or you can do it the hard way...

Do you have a "force" command?  It makes things easier, but it's not
an absolute requirement...

A very ugly way to achieve this can be done with a command that can TIOCSTI
input to yourself.

Basically, you:

1)	fork (command &)
2)	start the read in the child process
3)	ls -l the tty to check keyboard activity once a second
4)	use an eval to keep a second counter.
5)	When it hits the magic number of idle seconds, "force"
	a cr to the child process.
6)	exit the original process and let the child finish it's job
	with the "default" input.


There are several variations on this:

o	Do you need to keep the original process around instead
	of baton-relaying to one or more children?  You may need to
	use multiple child processes so that you can use the "jobs"
	command and write the child PID of the first child to the first
	child so it can tell it to it's child (I don't know how else to
	get parent process ID's in sh; sorry).  This will probably
	involve at least a sleep 2 in two processes.  8-(.

o	Do you want default input, or do you want to distinguish a
	timeout from anything a user can type?  If the latter, then
	you need to communicate the failure to read to the child,
	probably using a temp file or a pipe that you've assigned
	descriptors on.

o	Do you want to quit counting when there is any activity, like
	the boot prompt does?  You will need to modify the time
	comparison code accordingly, and exit the watchdog if you do.

o	Do you not have a "force"?  You will need a third process;
	do the watchdog, and do the read in the third process.  Use
	a pipe shared between both kids.  If the watchdog fires, kill
	the child doing the read and write a "WATCHDOG\n" up the
	pipe.  The original process should read the pipe for that,
	or if the read completes, kill the watchdog if it hasn't killed
	itself already (see above), and write the result of the read up,
	like "USERINPUT $x\n".  Look for the "WATCHDOG" as input,
	and if not there, strip the "USERINPUT " off the read result.

Ah, my misspent youth, writing complex installs in sh...

					Terry Lambert
					terry@lambert.org
---
Any opinions in this posting are my own and not those of my present
or previous employers.



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