Module: wine Branch: master Commit: b7a74d24f5e4b5c0d0ecaa63efaa15c5dda13b79 URL: http://source.winehq.org/git/wine.git/?a=commit;h=b7a74d24f5e4b5c0d0ecaa63ef...
Author: Andrew Nguyen anguyen@codeweavers.com Date: Tue Sep 28 03:48:13 2010 -0500
msvcrt: Implement strerror_s.
---
dlls/msvcr100/msvcr100.spec | 2 +- dlls/msvcr80/msvcr80.spec | 2 +- dlls/msvcr90/msvcr90.spec | 2 +- dlls/msvcrt/errno.c | 27 +++++++++++++++++++++++ dlls/msvcrt/msvcrt.spec | 2 +- dlls/msvcrt/tests/misc.c | 50 +++++++++++++++++++++++++++++++++++++++++++ include/msvcrt/string.h | 1 + 7 files changed, 82 insertions(+), 4 deletions(-)
diff --git a/dlls/msvcr100/msvcr100.spec b/dlls/msvcr100/msvcr100.spec index 5590d47..6d90b3b 100644 --- a/dlls/msvcr100/msvcr100.spec +++ b/dlls/msvcr100/msvcr100.spec @@ -1581,7 +1581,7 @@ @ cdecl strcpy_s(ptr long str) msvcrt.strcpy_s @ cdecl strcspn(str str) msvcrt.strcspn @ cdecl strerror(long) msvcrt.strerror -@ stub strerror_s +@ cdecl strerror_s(ptr long long) msvcrt.strerror_s @ cdecl strftime(str long str ptr) msvcrt.strftime @ cdecl strlen(str) msvcrt.strlen @ cdecl strncat(str str long) msvcrt.strncat diff --git a/dlls/msvcr80/msvcr80.spec b/dlls/msvcr80/msvcr80.spec index 8f547cf..c30ef6e 100644 --- a/dlls/msvcr80/msvcr80.spec +++ b/dlls/msvcr80/msvcr80.spec @@ -1435,7 +1435,7 @@ @ cdecl strcpy_s(ptr long str) msvcrt.strcpy_s @ cdecl strcspn(str str) msvcrt.strcspn @ cdecl strerror(long) msvcrt.strerror -@ stub strerror_s +@ cdecl strerror_s(ptr long long) msvcrt.strerror_s @ cdecl strftime(str long str ptr) msvcrt.strftime @ cdecl strlen(str) msvcrt.strlen @ cdecl strncat(str str long) msvcrt.strncat diff --git a/dlls/msvcr90/msvcr90.spec b/dlls/msvcr90/msvcr90.spec index 01df496..4e07480 100644 --- a/dlls/msvcr90/msvcr90.spec +++ b/dlls/msvcr90/msvcr90.spec @@ -1419,7 +1419,7 @@ @ cdecl strcpy_s(ptr long str) msvcrt.strcpy_s @ cdecl strcspn(str str) msvcrt.strcspn @ cdecl strerror(long) msvcrt.strerror -@ stub strerror_s +@ cdecl strerror_s(ptr long long) msvcrt.strerror_s @ cdecl strftime(str long str ptr) msvcrt.strftime @ cdecl strlen(str) msvcrt.strlen @ cdecl strncat(str str long) msvcrt.strncat diff --git a/dlls/msvcrt/errno.c b/dlls/msvcrt/errno.c index 4d97051..2e03ec1 100644 --- a/dlls/msvcrt/errno.c +++ b/dlls/msvcrt/errno.c @@ -219,6 +219,33 @@ char* CDECL MSVCRT_strerror(int err) }
/********************************************************************** + * strerror_s (MSVCRT.@) + */ +int CDECL strerror_s(char *buffer, MSVCRT_size_t numberOfElements, int errnum) +{ + char *ptr; + + if (!buffer || !numberOfElements) + { + *MSVCRT__errno() = MSVCRT_EINVAL; + return MSVCRT_EINVAL; + } + + if (errnum < 0 || errnum > MSVCRT__sys_nerr) + errnum = MSVCRT__sys_nerr; + + ptr = MSVCRT__sys_errlist[errnum]; + while (*ptr && numberOfElements > 1) + { + *buffer++ = *ptr++; + numberOfElements--; + } + + *buffer = '\0'; + return 0; +} + +/********************************************************************** * _strerror (MSVCRT.@) */ char* CDECL _strerror(const char* str) diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec index ccd3c6a..4fb9f8d 100644 --- a/dlls/msvcrt/msvcrt.spec +++ b/dlls/msvcrt/msvcrt.spec @@ -1374,7 +1374,7 @@ @ cdecl strcpy_s(ptr long str) MSVCRT_strcpy_s @ cdecl strcspn(str str) ntdll.strcspn @ cdecl strerror(long) MSVCRT_strerror -# stub strerror_s +@ cdecl strerror_s(ptr long long) @ cdecl strftime(str long str ptr) MSVCRT_strftime @ cdecl strlen(str) ntdll.strlen @ cdecl strncat(str str long) ntdll.strncat diff --git a/dlls/msvcrt/tests/misc.c b/dlls/msvcrt/tests/misc.c index 0e45eba..34980eb 100644 --- a/dlls/msvcrt/tests/misc.c +++ b/dlls/msvcrt/tests/misc.c @@ -25,6 +25,7 @@ static int (__cdecl *prand_s)(unsigned int *); static int (__cdecl *pmemcpy_s)(void *, MSVCRT_size_t, void*, MSVCRT_size_t); static int (__cdecl *pI10_OUTPUT)(long double, int, int, void*); +static int (__cdecl *pstrerror_s)(char *, MSVCRT_size_t, int);
static void init(void) { @@ -33,6 +34,7 @@ static void init(void) prand_s = (void *)GetProcAddress(hmod, "rand_s"); pmemcpy_s = (void*)GetProcAddress(hmod, "memcpy_s"); pI10_OUTPUT = (void*)GetProcAddress(hmod, "$I10_OUTPUT"); + pstrerror_s = (void *)GetProcAddress(hmod, "strerror_s"); }
static void test_rand_s(void) @@ -192,6 +194,53 @@ static void test_I10_OUTPUT(void) } }
+static void test_strerror_s(void) +{ + int ret; + char buf[256]; + + if (!pstrerror_s) + { + win_skip("strerror_s is not available\n"); + return; + } + + errno = EBADF; + ret = pstrerror_s(NULL, 0, 0); + ok(ret == EINVAL, "Expected strerror_s to return EINVAL, got %d\n", ret); + ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); + + errno = EBADF; + ret = pstrerror_s(NULL, sizeof(buf), 0); + ok(ret == EINVAL, "Expected strerror_s to return EINVAL, got %d\n", ret); + ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); + + memset(buf, 'X', sizeof(buf)); + errno = EBADF; + ret = pstrerror_s(buf, 0, 0); + ok(ret == EINVAL, "Expected strerror_s to return EINVAL, got %d\n", ret); + ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno); + ok(buf[0] == 'X', "Expected output buffer to be untouched\n"); + + memset(buf, 'X', sizeof(buf)); + ret = pstrerror_s(buf, 1, 0); + ok(ret == 0, "Expected strerror_s to return 0, got %d\n", ret); + ok(strlen(buf) == 0, "Expected output buffer to be null terminated\n"); + + memset(buf, 'X', sizeof(buf)); + ret = pstrerror_s(buf, 2, 0); + ok(ret == 0, "Expected strerror_s to return 0, got %d\n", ret); + ok(strlen(buf) == 1, "Expected output buffer to be truncated\n"); + + memset(buf, 'X', sizeof(buf)); + ret = pstrerror_s(buf, sizeof(buf), 0); + ok(ret == 0, "Expected strerror_s to return 0, got %d\n", ret); + + memset(buf, 'X', sizeof(buf)); + ret = pstrerror_s(buf, sizeof(buf), -1); + ok(ret == 0, "Expected strerror_s to return 0, got %d\n", ret); +} + START_TEST(misc) { init(); @@ -199,4 +248,5 @@ START_TEST(misc) test_rand_s(); test_memcpy_s(); test_I10_OUTPUT(); + test_strerror_s(); } diff --git a/include/msvcrt/string.h b/include/msvcrt/string.h index 3e60a4d..614fa85 100644 --- a/include/msvcrt/string.h +++ b/include/msvcrt/string.h @@ -44,6 +44,7 @@ static inline void* memccpy(void *s1, const void *s2, int c, size_t n) { return int __cdecl _strcmpi(const char*,const char*); char* __cdecl _strdup(const char*); char* __cdecl _strerror(const char*); +errno_t __cdecl strerror_s(char*,size_t,int); int __cdecl _stricmp(const char*,const char*); int __cdecl _stricoll(const char*,const char*); char* __cdecl _strlwr(char*);