2008-02-15 14:47:04 Interactive startup, or accessing stdin from /etc/rc
Steve Strobel (UNITED STATES)
Message: 51121 I usually start several daemons from /etc/rc. On occasion, I would like to prevent one of them from being loaded, possibly by pressing a key at a certain time during the boot process.
I attempted to accomplish that by writing a small detect-keypress program that uses tcsetattr() to switch the tty to raw mode, reads and prints any available input without blocking, then restores the tty settings and exits. It works fine when used from a script started manually from the shell prompt:
echo "Press a key to be detected or wait two seconds..."
sleep 2
key=`detect-keypress`
if [ "$key" != "" ]
then
echo "A keypress was detected: $key"
else
echo "No keypress detected"
fi
Unfortunately, when called from /etc/rc, it doesn't work. I presume that is because stdin isn't yet connected to /dev/console or something like that. I tried redirecting it with "detect-keypress < /dev/console", but that just hangs.
Any suggestions?
QuoteReplyEditDelete
2008-02-15 15:01:02 Re: Interactive startup, or accessing stdin from /etc/rc
Mike Frysinger (UNITED STATES)
Message: 51123 stdin is not hooked up on purpose for /etc/rc ... you dont want it to be interactive
if you want to hook up stdin, try adding this:
exec 0</dev/console
QuoteReplyEditDelete
2008-02-15 18:12:07 Re: Interactive startup, or accessing stdin from /etc/rc
Steve Strobel (UNITED STATES)
Message: 51131 Thanks for the reply.
Is the only reason that you wouldn't want /etc/rc to be interactive that you don't want it to get blocked, potentially forever? Is there a better way to make something happen automatically most of the time, but cancel it if desired (similar to what U-Boot does)? In my case, I was trying to use non-blocking I/O and a short sleep to let it complete normally if it wasn't canceled. Is that a bad idea?
I tried adding "exec 0</dev/console" to my script before calling detect keypress. That crashed, so I tried following it with just "read line". That crashes too. Even when entered just at a shell prompt, I get:
root:~> exec 0</dev/console
NULL pointer access (probably)
CURRENT PROCESS:
...
Do I have something wrong, or is that expected?
Is there a standard hook that I could use instead of /etc/rc that might happen later, after stdin is hooked up?
Steve
QuoteReplyEditDelete
2008-02-15 19:00:21 Re: Interactive startup, or accessing stdin from /etc/rc
Mike Frysinger (UNITED STATES)
Message: 51133 i'm just saying the default behavior is for /etc/rc to init the system ... if you want to do a timed reading of stdin, that's your business
what kernel version are you using ? running the proposed command works fine for me on 2008R1 and current trunk, and should in theory work fine for 2007R1 (since it uses the same busybox version as 2008R1)
QuoteReplyEditDelete
2008-02-18 10:06:07 Re: Interactive startup, or accessing stdin from /etc/rc
Steve Strobel (UNITED STATES)
Message: 51202 I am using Linux release 2.6.19.3-ADI-2007R1-svn135, build #308 Fri Feb 15 17:28:34 MST 2008
release 2007R1, build #518 Fri Feb 15 18:02:24 MST 2008 (the svn rev number is from my local repository).
I just did a "make clean && make" and get the same result. I guess I need to either do some post-mortem debugging or figure out what change I made is causing the problem. Thanks for the help.
Steve
QuoteReplyEditDelete
2008-02-20 12:40:53 Re: Interactive startup, or accessing stdin from /etc/rc
Steve Strobel (UNITED STATES)
Message: 51376 I haven't yet figured out why connecting stdin isn't working, but I found another easy solution for making the startup process interactive. I just made a script named "stop" that creates a file in the ram-based filesystem. The /etc/rc script sleeps for a second, then checks for the existence of that file, skipping the daemon load (and deleting the file) if it exists.
Now when I see the uClinux banner (from MOTD), I have a few seconds to type "stop" and press ENTER before /etc/rc checks for the file. I don't really need the extra delay that making /etc/rc sleep adds, but it doesn't seem to run the "stop" script without it.
Thanks again for your help,
Steve
QuoteReplyEditDelete
2008-02-21 10:52:12 Re: Interactive startup, or accessing stdin from /etc/rc
Andrea Federico Grisotto (ITALY)
Message: 51433 Hi Steve,
I want to suggest another solution.
I use a pseudo runlevel, I pass a string like this "runlevel=2" to the kernel boot parameters.
I set the runlevel in uBoot.
This is an example of uBoot setup:
-----------------------------------------------------------------
bootcmd=setenv autostart yes;run myboot
myboot=setenv bootargs $(bootargs) runlevel=$(runlevel) $(fsrootargs); $(nandargs)
runlevel=2
-----------------------------------------------------------------
After the linux boot in the rc file I parse the file ""/proc/cmdline" and look what is the runlevel,
using this script:
#######################################
# Extract variable values from cmdline
#######################################
count=0;
str="x";
while test "$str" != ""; # while no more arguments
do
# count++
count=`expr $count + 1`;
# extract element number $count e.g. "console=ttyBF0"
str=`cut -f $count -d ' ' /proc/cmdline`;
# extract first part e.g. "console"
variable=`echo $str | cut -f 1 -d '=' `
# extract second part e.g. "ttyBF0"
value=`echo $str | cut -f 2 -d '=' `
# if the first string is "runlevel" then save its value into runlevel
if test "$variable" = "runlevel"
then runlevel=$value; break;
fi
done
# ########################################################################
# RUNLEVEL
# ########################################################################
if [ $runlevel -eq 0 ]; then
echo "runlevel 0"
echo "etc. etc."
fi
if [ $runlevel -eq 1 ]; then
echo "runlevel 1"
echo "etc. etc."
fi
In this way, setting a runlevel I can choose what to do in the rc file.
I hope this can help you
Andrea.
QuoteReplyEditDelete
2008-02-21 13:27:56 Re: Interactive startup, or accessing stdin from /etc/rc
Mike Frysinger (UNITED STATES)
Message: 51435 if you're extracting "variables" only, you could stream line things easily:
eval $(grep -o '[^ ]*=[^ ]*' /proc/cmdline)
echo $root
echo $console
echo $runlevel
QuoteReplyEditDelete
2008-02-21 14:20:31 Re: Interactive startup, or accessing stdin from /etc/rc
Andrea Federico Grisotto (ITALY)
Message: 51437 Hi Mike,
you are right, thank you for the suggestion.