msvcrt: Implement strerror_s.

This commit is contained in:
Andrew Nguyen 2010-09-28 03:48:13 -05:00 committed by Alexandre Julliard
parent ac26d786c4
commit b7a74d24f5
7 changed files with 82 additions and 4 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -218,6 +218,33 @@ char* CDECL MSVCRT_strerror(int err)
return data->strerror_buffer;
}
/**********************************************************************
* 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.@)
*/

View File

@ -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

View File

@ -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();
}

View File

@ -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*);