The opendir(3) function was setting errno to ENOTDIR even when the directory existed and was opened successfully. This caused git to falsely detect an error. This change moves the errno assignment into the failure code block. It also adds a test to test24 to check for errno changing when opendir(3) returns success.
53 lines
1 KiB
C
53 lines
1 KiB
C
/* opendir() Author: Kees J. Bot
|
|
* 24 Apr 1989
|
|
*/
|
|
#define nil 0
|
|
#include <lib.h>
|
|
#define close _close
|
|
#define fcntl _fcntl
|
|
#define fstat _fstat
|
|
#define open _open
|
|
#define opendir _opendir
|
|
#define stat _stat
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <dirent.h>
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
#include <fcntl.h>
|
|
#include <errno.h>
|
|
|
|
DIR *opendir(const char *name)
|
|
/* Open a directory for reading. */
|
|
{
|
|
int d, f;
|
|
DIR *dp;
|
|
struct stat st;
|
|
|
|
/* Only read directories. */
|
|
if (stat(name, &st) < 0) return nil;
|
|
if (!S_ISDIR(st.st_mode)) { errno= ENOTDIR; return nil; }
|
|
|
|
if ((d= open(name, O_RDONLY | O_NONBLOCK)) < 0) return nil;
|
|
|
|
/* Check the type again, mark close-on-exec, get a buffer. */
|
|
if (fstat(d, &st) < 0
|
|
|| !S_ISDIR(st.st_mode)
|
|
|| (f= fcntl(d, F_GETFD)) < 0
|
|
|| fcntl(d, F_SETFD, f | FD_CLOEXEC) < 0
|
|
|| (dp= (DIR *) malloc(sizeof(*dp))) == nil
|
|
) {
|
|
int err= errno;
|
|
if (!S_ISDIR(st.st_mode)) err= ENOTDIR;
|
|
(void) close(d);
|
|
errno= err;
|
|
return nil;
|
|
}
|
|
|
|
dp->_fd= d;
|
|
dp->_count= 0;
|
|
dp->_pos= 0;
|
|
|
|
return dp;
|
|
}
|
|
|