[Date Prev][Date Next]
[Chronological]
[Thread]
[Top]
Re: (ITS#6041) opendir() and closedir() bugs on Windows
- To: openldap-its@OpenLDAP.org
- Subject: Re: (ITS#6041) opendir() and closedir() bugs on Windows
- From: hyc@symas.com
- Date: Mon, 30 Mar 2009 17:09:20 GMT
- Auto-submitted: auto-generated (OpenLDAP-ITS)
test.007@seznam.cz wrote:
> Full_Name: Test Seven
> Version: 2.4.15
> OS: Windows
> URL:
> Submission from: (NULL) (195.113.184.20)
Thanks for the patch. The Windows code is known to work fine using gcc. Use of
MSVC is discouraged since there have been so many incompatible CRT version
changes in such a short span of time. (Actually, use of Microsoft-anything is
generally discouraged; the same OpenLDAP code is at least 2-3x faster on the
same hardware when using Linux instead of Windows.)
> Two problems solved in the patch:
> 1. closedir()'s retval is used, thus it must not be void. Windows uses implicit
> declaration ``int closedir(int)'' because the function is not declared in
> headers, thus the call in ldif.c compiles, but uses random value in EAX.
>
> 2. opendir() must set errno, because ldif_readdir() reads it. The patch converts
> the most common Windows error codes to errno codes after FindFirstFile() WinAPI
> call.
>
> The bugs prevent me from loading cn=config configuration.
>
> --- utils.c.orig 2009-01-22 01:00:58.000000000 +0100
> +++ utils.c 2009-03-27 14:28:33.500000000 +0100
> @@ -466,6 +466,40 @@ int mkstemp( char * template )
> #endif
>
> #ifdef _MSC_VER
> +/* Equivalent of MS CRT's _dosmaperr().
> + * @param lastError[in] Result of GetLastError().
> + */
> +static errno_t win2errno(DWORD lastError)
> +{
> + const struct {
> + DWORD windows_code;
> + errno_t errno_code;
> + } WIN2ERRNO_TABLE[] = {
> + { ERROR_SUCCESS, 0 },
> + { ERROR_FILE_NOT_FOUND, ENOENT },
> + { ERROR_PATH_NOT_FOUND, ENOENT },
> + { ERROR_TOO_MANY_OPEN_FILES, EMFILE },
> + { ERROR_ACCESS_DENIED, EACCES },
> + { ERROR_INVALID_HANDLE, EBADF },
> + { ERROR_NOT_ENOUGH_MEMORY, ENOMEM },
> + { ERROR_NOT_ENOUGH_MEMORY, ENOMEM },
> + { ERROR_LOCK_VIOLATION, EACCES },
> + { ERROR_FILE_EXISTS, EEXIST },
> + { ERROR_INVALID_PARAMETER, EINVAL },
> + { ERROR_FILENAME_EXCED_RANGE, ENAMETOOLONG },
> + };
> + const unsigned int WIN2ERRNO_TABLE_SIZE = sizeof(WIN2ERRNO_TABLE) /
> sizeof(WIN2ERRNO_TABLE[0]);
> + const errno_t DEFAULT_ERRNO_ERROR = -1;
> + unsigned int i;
> +
> + for (i = 0; i< WIN2ERRNO_TABLE_SIZE; ++i) {
> + if (WIN2ERRNO_TABLE[i].windows_code == lastError) {
> + return WIN2ERRNO_TABLE[i].errno_code;
> + }
> + }
> + return DEFAULT_ERRNO_ERROR;
> +}
> +
> struct dirent {
> char *d_name;
> };
> @@ -493,9 +527,10 @@ DIR *opendir( char *path )
>
> h = FindFirstFile( tmp,&data );
>
> - if ( h == INVALID_HANDLE_VALUE )
> + if ( h == INVALID_HANDLE_VALUE ) {
> + errno = win2errno(GetLastError());
> return NULL;
> -
> + }
> d = ber_memalloc( sizeof(DIR) );
> if ( !d )
> return NULL;
> @@ -518,10 +553,11 @@ struct dirent *readdir(DIR *dir)
> }
> return&dir->data;
> }
> -void closedir(DIR *dir)
> +int closedir(DIR *dir)
> {
> FindClose(dir->dir);
> ber_memfree(dir);
> + return 0;
> }
> #endif
>
>
>
--
-- Howard Chu
CTO, Symas Corp. http://www.symas.com
Director, Highland Sun http://highlandsun.com/hyc/
Chief Architect, OpenLDAP http://www.openldap.org/project/