closedir(3) handling NULL

Warner Losh imp at bsdimp.com
Mon Jan 27 02:46:06 UTC 2014


On Jan 26, 2014, at 7:06 PM, kpneal at pobox.com wrote:

> On Fri, Jan 24, 2014 at 08:06:35PM +0200, Konstantin Belousov wrote:
>> On Fri, Jan 24, 2014 at 11:49:39AM -0600, Bryan Drewery wrote:
>>> 
>>> The code constructed a path, called opendir(3), received NULL, skipped
>>> over code that uses the entry since it was NULL, then called
>>> closedir(3).
>>> 
>>> Also, I don't find this very different than free(3) with a NULL. It's
>>> considered bad practice to check for NULL before calling it, why is
>>> closedir(3) any different?
>> 
>> Ok, so it does not have much to do with unmount, it is just an open
>> of nonexistent path.
>> 
>> I do not have an answer to the question about free(3), except that
>> free(NULL) behaviour is required by ANSI C, while closedir(NULL) is not,
>> by posix.
> 
> Wasn't free() accepting NULL a change that came in with C99? I thought
> that before then free() was only required to take valid pointers that came
> from one of the malloc() functions. So some systems accepted NULL and some
> did not.

No. C89 mandated free(NULL) to be a well defined nop. Can you give an example of one that conforms to Ansi C? It was unspecified in K&R first edition though.

From "7.20.3.2 The free function"
...
"void free(void *ptr);

The free function causes the space pointed to by ptr to be deallocated, that is, made
available for further allocation. If ptr is a null pointer, no action occurs."

K&R I (1988) says

"7.8.5 Storage Management
...
free(p) frees the space pointed to by p, where p was originally obtained by a call to malloc or 
calloc. There are no restrictions on the order in which space is freed, but it is a ghastly error to free 
something not obtained by calling malloc or calloc. "

Which is silent on the issue, although a null pointer is a pointer that can be returned from malloc (either as an error or as the unspecified behavior of malloc(0)). Early implementations varied widely in their behavior. bsd tended to favor 'dump core' while sys v favored the 'nop' behavior because it returned a null pointer for malloc(0).

So it has been well defined for 25 years: free(NULL) is a nop.

Warner


More information about the freebsd-standards mailing list