Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move from readdir_r to readdir #1955

Merged
merged 6 commits into from
Oct 10, 2017
Merged

Move from readdir_r to readdir #1955

merged 6 commits into from
Oct 10, 2017

Conversation

keghani
Copy link
Contributor

@keghani keghani commented Oct 9, 2017

b/31256592
Fixes #1307

Relevant man pages:
https://linux.die.net/man/3/readdir
https://linux.die.net/man/3/errno

@keghani keghani requested a review from hagbard October 9, 2017 10:36
Copy link
Member

@roubert roubert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't make any sense, according to the definition of errno any function call is free to modify it at will, the value is only guaranteed to carry any meaning after a function returns signalling that an error has occurred.

So saving and restoring a previous errno value should never be necessary, no code should depend on such behaviour.

if (res) {
errno = 0;
entry = readdir(dir);
if (errno) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The standard does actually not guarantee that a call to readdir() that returns a non-NULL pointer doesn't also modify errno, that guarantee is only specified for a call that returns NULL. So checking errno before checking the return value could possibly yield a false positive.

A safer implementation would be:

if (entry == NULL) {
return errno == 0;
}

@keghani
Copy link
Contributor Author

keghani commented Oct 9, 2017

Thanks Fredrik!
I had interpreted from https://linux.die.net/man/3/errno that if my call doesn't return -1 for success, I couldn't just leave errno at 0:

Valid error numbers are all nonzero; errno is never set to zero by any system call or library function.

For some system calls and library functions (e.g., getpriority(2)), -1 is a valid return on success. In such cases, a successful return can be distinguished from an error return by setting errno to zero before the call, and then, if the call returns a status that indicates that an error may have occurred, checking to see if errno has a nonzero value.

But I trust your judgment.
Made the changes. Thanks a lot!

}
if (dir_result == NULL) {
return true;
errno = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given Fredrik's comment that this is slightly unobvious behaviour, can you add a comment explaining this here.
Setting errno explicitly to success before a call is not something I'm used to seeing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fredrik's comment was on an outdated version of the file, I changed it. This is what he had suggested and if IIUC he doesn't think this one's unobvious - what he didn't think I should do was save the previous value of errno and set back to it if I come back with 0, which is what I had at commit 53642bf

Maybe let's discuss this in person. I'm happy with implementing it any way since you both know more here, but I'd like to understand it.

@keghani
Copy link
Contributor Author

keghani commented Oct 10, 2017

No worries, I read up some more and found http://pubs.opengroup.org/onlinepubs/009695399/functions/readdir.html and my questions are answered. This is the recommended way to use readdir, and I did add a comment to explain.

@keghani
Copy link
Contributor Author

keghani commented Oct 10, 2017

@roubert Done, thanks!
@hagbard ready for final look

Copy link
Contributor

@hagbard hagbard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@keghani keghani merged commit e95e140 into google:master Oct 10, 2017
@keghani keghani deleted the readdir branch October 10, 2017 14:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants