[patch] fbsplash

Denys Vlasenko vda.linux at googlemail.com
Fri Apr 4 17:17:01 UTC 2008


On Friday 04 April 2008 11:27, Michele Sanges wrote:
> Hello,
> 
> while fbsplash works well in root fs, it doesn't work when started from
> an initrd. It exhibits this behavior:
> 
> 1. the nash shell, used in initrd, can't start the applet in background;
> it blocks forever the loading process.
> 
> ==> I added back the code to fork the process (if this can be
> acceptable).

I'm sorry, but it is not acceptable. In Unix, each tool should do
one thing. fbsplash should not be hardwired for one application
(boot splash). What is someone needs to want for fbsplash to finish?

Make it so that people who want to background it, can do it,
and the rest is not forced to do so.

If you are using a shell which is incapable of backgrounding
processes, write a helper tool, say:

daemon <cmd> <params>

which forks, child execs "<cmd> <params>", and parent exits.


+       if (*fifo_filename != '-') {

You disallow names like "-foo"?

+               // opens the fifo twice
+               fd_r = xopen(fifo_filename, O_RDONLY);
+               fd_w = xopen(fifo_filename, O_WRONLY);  // only for make the 'read' blocking
+       }
+       else {
+               fd_r = xopen("/dev/stdin", O_RDONLY);

How about just using file descriptor 0?

> 2. once started with the above fork code, if I want to redirect the
> messages from the console to the uart, passing to the kernel the option
> 'console=uart', it doesn't receive the commands from the fifo.

Why?

> ==> I substitute the file manipulation library functions (fopen,
> fgetline, fclose..) with the system one (open, read, close..) and thus
> it works.

Well, it would be nice to understand why it makes a difference.

> Il giorno ven, 28/03/2008 alle 09.06 -0400, Paul Fox ha scritto:
> > is the proper solution simply to open it twice, once for reading,
> > and once for writing?  this guarantees a writer (which will never
> > write anything).
> 
> Following the suggestion of Paul, now I open the fifo twice to use the
> opportunity to make the read blocking.

How about achieving it like this:

        fp = xfopen_stdin(fifo_filename);
+       if (fp != stdin)
+               open(fifo_filename, O_WRONLY);

and removing this part:

                // We got EOF/error on fp
                if (ferror(fp))
                        goto exit_cmd;
                fclose(fp);
                if (LONE_DASH(fifo_filename)
                 || stat(fifo_filename, &statbuf) != 0
                 || !S_ISFIFO(statbuf.st_mode)
                ) {
                        goto exit_cmd;
                }
                // It's really a named pipe!
                // For named pipes, we want to support this:
                //  mkfifo cmd_pipe
                //  fbsplash -f cmd_pipe .... &
                //  ...
                //  echo 33 >cmd_pipe
                //  ...
                //  echo 66 >cmd_pipe
                // This means that on EOF, we need to close/open cmd_pipe
                // (just reading again works too, but it hogs CPU)
                fp = xfopen_stdin(fifo_filename); // blocks on open


> After reading, the buffer is 
> scanned in order to take the last command line.

+               cmd_buf[nlen] = '\0';
+
+               // when we have many buffered lines already in the pipe, takes the last one.
+               p = cmd_buf;
+               last_cmd = cmd_buf;
+               while (((p = strchr(last_cmd, '\n')) != (cmd_buf + nlen - 1)) && (p != NULL)) {
+                       last_cmd = (p + 1);
+               }

This will break if we get, say, 34 byte long string:

"1\n2\n3\n.....\n34\n"

read will eat 32 bytes: "1\n2\n3\n.....\n3"

and you will display 3% bar.

--
vda



More information about the busybox mailing list