2008-02-15 14:47:04     Interactive startup, or accessing stdin from /etc/rc

Document created by Aaronwu Employee on Aug 5, 2013
Version 1Show Document
  • View in full screen mode

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.

Attachments

    Outcomes