From: Flash Gordon said:
So it still was not needed in the program you posted.
That depends on how you think of the program. If it had been
intended as a standalone program to distribute to others, then the
sleep could be regarded as a "dunzell" (StarTrek TOS jargon), i.e.
a part that serves no useful function. However in fact it was just
a test rig to develop modules which would later be installed
primarily in a CGI environment (where the toplevel stdin test loop
would not be present at all). As a test rig, where I might at any
time add new buggy code that might produce infinite spew, whereby
I'd need protection from modem-buffer disaster, it was quite
appropriate for the sleep to be in the toplevel loop at all times.
What was posted was just the current version of that test rig at
the moment I posted. But in fact that sleep would be present in
*any* version of that test rig at any time after I encountered the
modem-buffer disaster and consequently took precautions against it
ever happening again in any version of that test rig or any other
test rig descended from it.
If anyone happens to like my program enough to copy it and use it
themselves, but doesn't like the sleep in it, feel free to remove
it, but then don't complain to me if you subsequently try to modify
the program in other ways and introduce a bug and fill up your
modem buffers or even worse fill up all free swap space on your PC
and crash the OS and can't re-boot. (YMMV)
That is because it is the wrong approach
1) read the documentation to see what the correct way to do it is
2) write the code
3) test it
That's not good development technique. Documentation often is
misunderstood. If your approach is followed, your program might
have a subtle bug where you're not getting the value you thought
you're getting but you have the test written backwards or otherwise
wrong and for the cases you tested your multiple mistakes are
covering for each other making the program "work" despite being
totally wrongly written.
It's best to read the documentation (as I did, but did't include in
the steps of actual program development, sorry if you assumed
contrary to fact), and the install both the call to whatever
library routine *and* a printf of the return value, then look at
the output to see if it conforms to how you read the documentation
to mean, and if so then proceed to write the test on that basis.
But if the return value doesn't agree with what you thought the
documentation said, you need to consider various alternatives:
- You aren't calling the correct function because you loaded the
wrong library.
- You are calling the correct function in the wrong way (as
happened to me the first time I tried strtoll, see other thread).
- You misunderstood the documentation.
Once you are sure the function returns the value you expect in all
test cases that cover in-range out-of-range cases as well as
carefully constructed right-at-edge-of-range cases, if any of that
makes sense for the given fuction, *then* it's time to write the
test to distinguish between the various classes of results as you
now *correctly* understand them based on agreement between your
reading of documentation and your live tests.
So in this case, calling fgets, I needed to test all these cases:
- Empty input: NonNull return value, Buffer contains EOL NUL
- Normal input: NonNull return value, Buffer contains chars EOL NUL
- Input that overruns buffer: NonNull return value, Buffer contains chars NUL
- Abort via end-of-stream generated via ctrl-D: NULL return value.
- Abort via ctrl-C: Program aborts to shell all by itself.
- Abort via escape (a.k.a. altmode): Goes in as garbage screwup character, avoid.
One case (buffer overrun) I really needed to see for myself,
because the documentation didn't make it clear whether fgets would
omit the NUL so it could fill the entire buffer with data to cram
it all in and not lose that last character, or truncate the data
one shorter to guarantee a NUL was there. In fact the latter
occurs. But I was prepared to force a NUL there, overwriting the
last byte, if fgets had done the first instead. One thing I *did*
have to do is check whether the last character before the NUL was
EOL or not, and clobber it to NUL (shortening string by one
character per c's NUL-terminated-byte-array convention for
emulating "strings") only if it was EOL, so the string seen by the
rest of the program would consistently *not* have the EOL
character.
Now not all those cases are actually necessary for the end purpose
of this program, developing a module intended for CGI usage, but
it's nice to know my how the basic terminal-input routine of my
stdin test rig performs for *all* inputs before making extensive
use of it for *anything*. I don't want confusion later where I
don't know whether strange results are due to bug in test rig or
bug in the actual module I'm trying to develop.
Wrong. C does not allow *any* sleeping. ...
Let me re-phrase that: The sleep function provided by the library
whose header is unistd.h doesn't allow any sleep times except
integers. Now are you happy?