[Toybox] Toybox Digest, Vol 21, Issue 8

Rob Landley rob at landley.net
Thu Jul 18 16:40:53 PDT 2013


On 07/17/2013 07:24:31 AM, Kyungwan Han wrote:
> Hello all.
> 
> I have a basic question.
> 
> I have known that "Magic number should not used in the code."
> But I checked Rob's review comments and I come to know my though is  
> wrong.
> 
> Then, when should I use MACRO instead of magic number?

I prefer not to use magic numbers in code, but if you #define the magic  
number
in the same file you use it in, that's "in the code".

When you can #include it from a reasonably portable header file, do so.
When you _can't_ get it from a header file, and you have to #define a  
local
constant for your own use, the normal "this is only used once, just  
inline
the #define" rules apply. (Then I add a comment about what the symbol  
name
would be, because the number needs explaining. But if you're going to  
have
a magic number anyway, gratuitously separating the definition and the  
use
serves no purpose.)

> And close() is not strictly requried in the comments,
> but I also know close() MUST be there.
> Is my thought wrong?

When a program exits, the system does a lot of cleanup for us. It frees  
our
memory, closes filehandles, unmaps mmap(), and so on.

If you have a loop that leaks a filehandle, you can run out of  
filehandles.
But if you open a filehandle, write to it, and then exit, the system  
will
close it for you. That's the "not strictly needed" part. Calling cleanup
functions right before we discard the entire process context makes the
program bigger without actually accomplishing anything; stdio will  
flush()
for us, and so on.

That said, running under debuggers like valgrind will complain about  
all sorts
of leaked resources at exit, and if you're looking for persistent leaked
resources (of the kind that would add up in a long-running program),
eliminating these _intentional_ leaks to cut down on the noise makes
valgrind easier to use. Hence the CFG_TOYBOX_FREE symbol.

Plus if we have any NOFORK programs (which toysh can call without  
forking
a new process context), they can't leak resources. (Those are the ones  
the
xexit() longjmp() stuff is for.) That said, most things _can't_ safely
be called nofork, but if we do build toysh it migth turn on  
CFG_TOYBOX_FREE
to potentially turn a few more commands into NOFORK versions that could
run in shell scripts faster. (Some commands _must_ be NOFORK because  
they
modify the shell's process context. "cd", "exit", "set..." lots of shell
builtins have to be that way. But as long as you've got that, there's no
reason "true" and "false" can't be too, and then maybe echo...)

Rob

P.S. The comment about only NFS needing xclose() is because the only
filesystem that can actually return an error from close() is NFS. Nobody
ever checks the return code from close because nobody cares about NFS,  
it's
trivially easy to break that filesystem:

   mkdir sub && rm -rf sub > sub/file

NFS is _crap_. I'm working on a 9p server for toybox to help render it
obsolete. (I can do a writeup on why 9p is cool if you're curious...)
 1374190853.0


More information about the Toybox mailing list