2

So I was reading a book on writing a shell in C and I want to try to write it in C++. I came across the following code:

for( ; ; ) 
{
    if (fputs(PROMPT, stdout) == EOF)
        continue;

    if (fgets(inbuf, MAX, stdin) == NULL)
        continue;

    //and so on....
}
  1. I don't understand the usage of fputs() here.

    (a) if stdout is a terminal, does EOF have any meaning? What kind of errors can you get writing to a terminal except maybe the stream is already closed?

    (b) if stdout was previously redirected and is really a pipe or file then several different errors seem possible. Where are they listed? See (c) below.

    (c) following (b) above, ferror() doesn't seem that helpful. Does its return values map to those of errno and thus the same as using something like perror()? Where are the constants kept in order to do something like

      if (ferror() == SYSTEM_ERROR_13)
    

    (d) in the code above, if fputs() did return an error why would a "continue" work? Wouldn't the error need to be cleared first with something like clearerr() or it would just repeatedly fail?

  2. Is the equivalent code in C++:

    for( ; ; ) 
    {
        if (! cout << PROMPT)
        {
            cout.clear();
            continue;
        }
    
        if (! getline(cin, inbuf))
        {
            cin.clear();
            continue;
        }
    
        //and so on....
    }
    
Translucent Pain
  • 1,441
  • 2
  • 14
  • 18
  • 1
    In my personal view, if an interactive shell loses either input or output stream, it should terminate. You can't be interactive without interaction. – Kerrek SB Jan 30 '12 at 05:05
  • So it should just die? If you lose stdout/stderr is it appropriate to try and write to a system log? If your shell was started by something like a system() call from another program is there an appropriate exit value to pass back? – Translucent Pain Jan 30 '12 at 05:33
  • You could treat it the same way as if the user requested a quit and shut down normally. Like Bash, for example, when you press Ctrl-D. – Kerrek SB Jan 30 '12 at 05:39

1 Answers1

1
if (fputs(PROMPT, stdout) == EOF)
    continue;

a) if stdout is a terminal, does EOF have any meaning? - fputs function returns EOF on error.

b) different errors seem possible. Where are they listed? - Does the reason why writing into stdout has failed really matter? Are you sure you want to go that deep?

c) ferror() doesn't seem that helpful ... using something like perror()? They both work based on the global variable errno. Although perror would be much better option for you, since it makes the output in specified format to stderr.

d) in the code above, if fputs() did return an error why would a "continue" work? - This seems to be incorrect.

According to these facts, it should look like this:

if (fputs(PROMPT, stdout) == EOF)
{
    perror("The following error occurred");
    exit(1);
}

if (fgets(inbuf, MAX, stdin) == NULL)
{
    perror("The following error occurred");
    continue;
}

2. Is the equivalent code in C++ ? - No. There is one difference: fgets reads the line and '\n' is included in the string, while getline reads the line but delimiter ('\n') is not stored.

LihO
  • 41,190
  • 11
  • 99
  • 167