Closed Bug 285286 Opened 20 years ago Closed 20 years ago

PR_ReadDir does not notify correcly end of directory

Categories

(NSPR :: NSPR, defect)

defect
Not set
normal

Tracking

(Not tracked)

RESOLVED FIXED

People

(Reporter: poumeyrol, Assigned: wtc)

Details

Attachments

(1 file, 1 obsolete file)

User-Agent:       Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/188 (KHTML, like Gecko) Safari/188
Build Identifier: 

PR_ReadDir sets NSPR error status to PR_UNKNOWN_ERROR instead of PR_NO_MORE_FILES_ERROR when 
reaching end of directory.

The cause is readdir returns NULL and set errno to 0 when reaching the end of the directory, whereas 
_MD_unix_readdir_error from unix_errors.c only except ENOENT in such a case.

Reproducible: Always

Steps to Reproduce:
#include <prio.h>

int main()
{
    PRDir * dir = PR_OpenDir(".");
    while(PR_ReadDir(dir, PR_SKIP_BOTH)) ;
    PR_fprintf(PR_STDERR, "PR_GetError returns %d\n", PR_GetError());
    return 0;
}
Actual Results:  
PR_GetError returns -5994
PR_UNKNOWN_ERROR better, but still wrong...

Expected Results:  
PR_GetError returns -5939 
That is PR_NO_MORE_FILES -> OK.

if the program says "PR_GetError returns 0" you have to apply the patch from #279323.
Attached patch fix proposal (obsolete) — Splinter Review
Thanks for the bug report and fix.

The Single UNIX Specification Version 3 also
recommends that we set errno to 0 before each
readdir call, which is what my patch does.  I
also fix the similar code in BeOS.  Not sure
if that's correct or needed though.
Attachment #176727 - Attachment is obsolete: true
Here is the URL for the readdir man page in the
Single UNIX Specification Version 3:
http://www.opengroup.org/onlinepubs/009695399/functions/readdir.html
Status: UNCONFIRMED → ASSIGNED
Ever confirmed: true
Attachment #176803 - Flags: review?(bryner)
Attachment #176803 - Flags: review?(bryner) → review+
Attachment #176803 - Flags: superreview?(thesuckiestemail)
tqh, sergei_d: could you look up BeOS's readdir()
documentation and tell me what it says about readdir's
return value and errno when readir() reaches the end of
the directory?  Then, please review the BeOS portion of
my patch.  Please use the "superreview" checkbox
to indicate your review.  Thanks.
I checked in the patch (proposal v1.1) on the
NSPR trunk (NSPR 4.6) and NSPRPUB_PRE_4_2_CLIENT_BRANCH
(Mozilla 1.8 Beta 2).

SUSv3 says:

  The readdir() function may fail if:

  [ENOENT]
      The current position of the directory stream is invalid.

This suggests that ENOENT doesn't mean the end of the
directory is encountered, so it is wrong to map ENOENT
to PR_NO_MORE_FILES_ERROR.  Not sure if we should fix
this though.
Status: ASSIGNED → RESOLVED
Closed: 20 years ago
Resolution: --- → FIXED
Target Milestone: --- → 4.6
Comment on attachment 176803 [details] [diff] [review]
fix proposal v1.1

There is no BeOS specific docs on readdir so it should behave the same as most
others, returning NULL if no more entries.
Attachment #176803 - Flags: superreview?(thesuckiestemail) → superreview+
tqh: do you know whether readdir() sets the errno
when it encounters the end of the directory?  This
is what I really want to know.
Wrote a program which reports: "readdir returned NULL with following errno: 0 No
Error"

int main() {
	DIR * aDir = opendir("/boot/home/");
	if( aDir == NULL ) {
		cout << "opendir failed: " << errno << " " << strerror(errno) << endl;
		return 1;	
	}
	
	struct dirent * aDirEntry;
	do {
		aDirEntry = readdir( aDir );	
		if( aDirEntry == NULL ) break;
		cout << aDirEntry->d_name << endl;
	} while( true );
	cout << "readdir returned NULL with following errno: " << errno << " " <<
strerror(errno) << endl;
	closedir(aDir);
	return 0;
}


Thank you, tqh.
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: