News for hackers. Stuff that matters.
Re:fork() can fail by mutation on Wednesday August 20, 2014 @04:00PM (#8204237)
Just noticed that in Perl the behavior is slightly different: http://perldoc.perl.org/functions/fork.html unsuccessful fork() returns undef, effectively stopping you from kill-ing what you don't want to kill.
Re:fork() can fail by takeda on Wednesday August 20, 2014 @05:30PM (#8204768)
Similarly python throws an exception, and I bet other languages have their own behaviors, but in case of C this is the only way (or at least it is the only non complicated way to do it).

When I read this article I thought it was preaching to a choir. I'm actually quite surprised people programming C don't check for errors. That's the only way the functions can provide a feedback.

Re:fork() can fail by _yosefk on Wednesday August 20, 2014 @06:14PM (#8204978)
Nothing in C forces the API designer to use -1 as "bad PID" in one place and as "the set of all PIDs" in another, however. Perl's undef isn't that different from returning, gosh, -2 or any other bloody number except -1 in C.
Re:fork() can fail by takeda on Wednesday August 20, 2014 @06:54PM (#8205116)
Actually this is not true.

fork() returns pid_t type which is usually mapped to int32_t. For this type there's no equivalent of Perl's "undef", the -1 is standardized as an error in all system calls that return an integer.

As for the argument why not send -2 instead, well guess what? Other negative values also have a meaning. Negative values in kill send signal to a process group instead of a process.

It's not libc responsibility to predict all possible things the programmer can do. Also unlike perl, C doesn't have exceptions so it can't exactly quickly terminate on error showing what went wrong.

Imagine C throwing SIGSEGV every single time a function failed.

Re:fork() can fail by lmm on Thursday August 21, 2014 @02:33AM (#8206138)
> As for the argument why not send -2 instead, well guess what? Other negative values also have a meaning. Negative values in kill send signal to a process group instead of a process.

That's the problem there. Kill takes an argument that's either a process id or a magic number or a different magic number or.... Those should be different functions, and the special cases like "kill all processes", "kill all processes in this group",... should be some kind of enumeration type. But it's C, so...

Re:fork() can fail by maxlybbert on Wednesday August 20, 2014 @08:01PM (#8205324)
> Perl's undef isn't that different from returning, gosh, -2 or any other bloody number except -1 in C.

Returning undef has the advantage of being something completely useless as a process ID for any other function call.

Re:fork() can fail by aiiane on Thursday August 21, 2014 @12:02AM (#8205887)
Not actually true. Modifying arguments that were passed in is another. :)
Re:fork() can fail by pflanze on Thursday August 21, 2014 @01:49AM (#8206070)
Interestingly, the kill procedure in Perl explicitely checks for non-numbers, which is unusual. Perl as a language would just cast undef to zero in a numeric context[1], and 'kill $signal, 0' would go on killing every process in the process group.

  $ perl -we 'kill 9, undef'
  Can't kill a non-numeric process ID at -e line 1.
[1] unless you "use warnings FATAL => 'uninitialized';"
Re:fork() can fail by epochwolf on Wednesday August 20, 2014 @04:57PM (#8204568)
In C, there is no concept of null or undefined, only 0.
Re:fork() can fail by dllthomas on Wednesday August 20, 2014 @05:11PM (#8204664)
That's not quite true, but not a terrible approximation.
Re:fork() can fail by sdegutis on Wednesday August 20, 2014 @05:23PM (#8204730)
How is it not true? Besides void expressions (which aren't values) the above poster's statement appears correct.
Re:fork() can fail by dllthomas on Wednesday August 20, 2014 @05:29PM (#8204763)
A null pointer does not need to have an all-zero representation, which mattered once on some architectures. I'm not aware of any current architecture that does it that way, but that's still what the standard says, which is to say that C does technically have a notion of null which is not necessarily identical with 0.

http://c-faq.com/null/machexamp.html

Re:fork() can fail by spc476 on Wednesday August 20, 2014 @05:38PM (#8204805)
But in C, a 0 in a pointer context is always considered the NULL pointer (even if the physical value of a NULL pointer isn't all zeros).
Re:fork() can fail by cperciva on Wednesday August 20, 2014 @06:14PM (#8204972)
Only a compile-time constant zero. So

    assert(NULL == (void *)0);
is fine, but

    int x = 0;
    assert(NULL == (void *)x);
is not.
Re:fork() can fail by loup-vaillant on Wednesday August 20, 2014 @06:13PM (#8204966)
Additionally in a boolean context a null pointer is indistinguishable from "false" (meaning, zero).

http://c-faq.com/null/ptrtest.html

For practical purposes, the null pointer and the integer `0` are one and same.

Re:fork() can fail by dllthomas on Wednesday August 20, 2014 @07:34PM (#8205236)
"For practical purposes, the null pointer and the integer `0` are one and same."

For most practical purposes, which is why I said that it wasn't a terrible approximation. However, they can be distinguished on some architectures:

    intptr_t x = 0;
    void *p = 0;
    
    x == *(intptr_t*)(char*)&p;
I can easily construct fantasy scenarios (involving more than a bit of Doing It Wrong) where this would be relevant. I'm not convinced it couldn't ever be relevant without Doing It Wrong, if one in fact needed to work on that kind of a system.