mirror of
https://github.com/reactos/wine.git
synced 2024-11-24 20:30:01 +00:00
msvcrt: Implement strerror_s.
This commit is contained in:
parent
ac26d786c4
commit
b7a74d24f5
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.@)
|
||||
*/
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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*);
|
||||
|
Loading…
Reference in New Issue
Block a user