Re: (ITS#6041) opendir() and closedir() bugs on Windows
by hyc@symas.com
test.007(a)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/
14 years, 6 months
Re: (ITS#6041) opendir() and closedir() bugs on Windows
by hyc@symas.com
test.007(a)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/
14 years, 6 months
Re: (ITS#6041) opendir() and closedir() bugs on Windows
by hyc@symas.com
test.007(a)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/
14 years, 6 months
Re: (ITS#6041) opendir() and closedir() bugs on Windows
by hyc@symas.com
test.007(a)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/
14 years, 6 months
Re: (ITS#6041) opendir() and closedir() bugs on Windows
by hyc@symas.com
test.007(a)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/
14 years, 6 months
Re: (ITS#6041) opendir() and closedir() bugs on Windows
by hyc@symas.com
test.007(a)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/
14 years, 6 months
Re: (ITS#6041) opendir() and closedir() bugs on Windows
by hyc@symas.com
test.007(a)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/
14 years, 6 months
Re: (ITS#6038) Write slapadd progress meter to stdout
by michael@stroeder.com
rein(a)OpenLDAP.org wrote:
> For programs that produce real output (slapcat, ldapsearch) this might
> be true, but for those that don't (slapadd, slapd) I totally disagree.
> Stderr is for errors, not chatty progress or debug messages. I always
> hate it when the error messages gets burried in lots of noice.
>
> My preference is to have progress and debug messages on stdout, enabled
> by options or at least possible to disable by options. Real output must
> be possible to send to a file specified as argument, to separate it from
> the progress and debug noice. Stderr is for error messages, and
> possibly out-of-band messages.
+1
Ciao, Michael.
14 years, 6 months
(ITS#6041) opendir() and closedir() bugs on Windows
by test.007@seznam.cz
Full_Name: Test Seven
Version: 2.4.15
OS: Windows
URL:
Submission from: (NULL) (195.113.184.20)
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
14 years, 6 months