Piotr Caban : msvcr100: Added fread_s implementation.
Alexandre Julliard
julliard at winehq.org
Wed Dec 12 15:14:54 CST 2012
Module: wine
Branch: master
Commit: 101abcd8b119853ff70449be27e2322b16bbaf47
URL: http://source.winehq.org/git/wine.git/?a=commit;h=101abcd8b119853ff70449be27e2322b16bbaf47
Author: Piotr Caban <piotr at codeweavers.com>
Date: Wed Dec 12 11:14:48 2012 +0100
msvcr100: Added fread_s implementation.
---
dlls/msvcr100/msvcr100.c | 54 +++++++++++++++++++++++++++
dlls/msvcr100/msvcr100.spec | 2 +-
dlls/msvcr100/tests/msvcr100.c | 80 ++++++++++++++++++++++++++++++++++++++++
dlls/msvcr80/msvcr80.spec | 2 +-
dlls/msvcr90/msvcr90.spec | 2 +-
include/msvcrt/limits.h | 8 ++++
6 files changed, 145 insertions(+), 3 deletions(-)
diff --git a/dlls/msvcr100/msvcr100.c b/dlls/msvcr100/msvcr100.c
index 5778940..f529b10 100644
--- a/dlls/msvcr100/msvcr100.c
+++ b/dlls/msvcr100/msvcr100.c
@@ -25,6 +25,7 @@
#include "stdlib.h"
#include "errno.h"
#include "malloc.h"
+#include "limits.h"
#include "sys/stat.h"
#include "windef.h"
#include "winbase.h"
@@ -404,6 +405,59 @@ unsigned __int64 CDECL _byteswap_uint64(unsigned __int64 i)
}
/*********************************************************************
+ * fread_s (MSVCR100.@)
+ */
+size_t CDECL fread_s(void *buf, size_t buf_size, size_t elem_size, size_t count, FILE *stream)
+{
+ size_t bytes_left, buf_pos;
+
+ TRACE("(%p %lu %lu %lu %p\n", buf, (unsigned long)buf_size,
+ (unsigned long)elem_size, (unsigned long)count, stream);
+
+
+ if(!CHECK_PMT(stream != NULL)) {
+ if(buf && buf_size)
+ memset(buf, 0, buf_size);
+ return 0;
+ }
+ if(!elem_size || !count) return 0;
+ if(!CHECK_PMT(buf != NULL)) return 0;
+ if(!CHECK_PMT(SIZE_MAX/count >= elem_size)) return 0;
+
+ bytes_left = elem_size*count;
+ buf_pos = 0;
+ while(bytes_left) {
+ if(stream->_cnt > 0) {
+ size_t size = bytes_left<stream->_cnt ? bytes_left : stream->_cnt;
+
+ if(!CHECK_PMT_ERR(size <= buf_size-buf_pos, ERANGE)) {
+ memset(buf, 0, buf_size);
+ return 0;
+ }
+
+ fread((char*)buf+buf_pos, 1, size, stream);
+ buf_pos += size;
+ bytes_left -= size;
+ }else {
+ int c = _filbuf(stream);
+
+ if(c == EOF)
+ break;
+
+ if(!CHECK_PMT_ERR(buf_size-buf_pos > 0, ERANGE)) {
+ memset(buf, 0, buf_size);
+ return 0;
+ }
+
+ ((char*)buf)[buf_pos++] = c;
+ bytes_left--;
+ }
+ }
+
+ return buf_pos/elem_size;
+}
+
+/*********************************************************************
* DllMain (MSVCR100.@)
*/
BOOL WINAPI DllMain(HINSTANCE hdll, DWORD reason, LPVOID reserved)
diff --git a/dlls/msvcr100/msvcr100.spec b/dlls/msvcr100/msvcr100.spec
index 162ad65..70fca053 100644
--- a/dlls/msvcr100/msvcr100.spec
+++ b/dlls/msvcr100/msvcr100.spec
@@ -1669,7 +1669,7 @@
@ cdecl fputwc(long ptr) msvcrt.fputwc
@ cdecl fputws(wstr ptr) msvcrt.fputws
@ cdecl fread(ptr long long ptr) msvcrt.fread
-@ stub fread_s
+@ cdecl fread_s(ptr long long long ptr)
@ cdecl free(ptr) msvcrt.free
@ cdecl freopen(str str ptr) msvcrt.freopen
@ cdecl freopen_s(ptr str str ptr) msvcrt.freopen_s
diff --git a/dlls/msvcr100/tests/msvcr100.c b/dlls/msvcr100/tests/msvcr100.c
index 366e8ee..143979d 100644
--- a/dlls/msvcr100/tests/msvcr100.c
+++ b/dlls/msvcr100/tests/msvcr100.c
@@ -20,6 +20,7 @@
#include <stdarg.h>
#include <stdlib.h>
#include <wchar.h>
+#include <stdio.h>
#include <windef.h>
#include <winbase.h>
@@ -68,6 +69,9 @@ static void __cdecl test_invalid_parameter_handler(const wchar_t *expression,
static int* (__cdecl *p_errno)(void);
static int (__cdecl *p_wmemcpy_s)(wchar_t *dest, size_t numberOfElements, const wchar_t *src, size_t count);
static int (__cdecl *p_wmemmove_s)(wchar_t *dest, size_t numberOfElements, const wchar_t *src, size_t count);
+static FILE* (__cdecl *p_fopen)(const char*,const char*);
+static int (__cdecl *p_fclose)(FILE*);
+static size_t (__cdecl *p_fread_s)(void*,size_t,size_t,size_t,FILE*);
/* make sure we use the correct errno */
#undef errno
@@ -91,6 +95,9 @@ static BOOL init(void)
SET(p_set_invalid_parameter_handler, "_set_invalid_parameter_handler");
SET(p_wmemcpy_s, "wmemcpy_s");
SET(p_wmemmove_s, "wmemmove_s");
+ SET(p_fopen, "fopen");
+ SET(p_fclose, "fclose");
+ SET(p_fread_s, "fread_s");
return TRUE;
}
@@ -247,6 +254,78 @@ static void test_wmemmove_s(void)
"Cannot reset invalid parameter handler\n");
}
+static void test_fread_s(void)
+{
+ static const char test_file[] = "fread_s.tst";
+ int ret;
+ char buf[10];
+
+ FILE *f = fopen(test_file, "w");
+ if(!f) {
+ skip("Error creating test file\n");
+ return;
+ }
+ fwrite("test", 1, 4, f);
+ fclose(f);
+
+ ok(p_set_invalid_parameter_handler(test_invalid_parameter_handler) == NULL,
+ "Invalid parameter handler was already set\n");
+
+ SET_EXPECT(invalid_parameter_handler);
+ errno = 0xdeadbeef;
+ ret = p_fread_s(buf, sizeof(buf), 1, 1, NULL);
+ ok(ret == 0, "fread_s returned %d, expected 0\n", ret);
+ ok(errno == EINVAL, "errno = %d, expected EINVAL\n", errno);
+ CHECK_CALLED(invalid_parameter_handler);
+
+ f = p_fopen(test_file, "r");
+ errno = 0xdeadbeef;
+ ret = p_fread_s(NULL, sizeof(buf), 0, 1, f);
+ ok(ret == 0, "fread_s returned %d, expected 0\n", ret);
+ ok(errno == 0xdeadbeef, "errno = %d, expected 0xdeadbeef\n", errno);
+ ret = p_fread_s(NULL, sizeof(buf), 1, 0, f);
+ ok(ret == 0, "fread_s returned %d, expected 0\n", ret);
+ ok(errno == 0xdeadbeef, "errno = %d, expected 0xdeadbeef\n", errno);
+
+ SET_EXPECT(invalid_parameter_handler);
+ errno = 0xdeadbeef;
+ ret = p_fread_s(NULL, sizeof(buf), 1, 1, f);
+ ok(ret == 0, "fread_s returned %d, expected 0\n", ret);
+ ok(errno == EINVAL, "errno = %d, expected EINVAL\n", errno);
+ CHECK_CALLED(invalid_parameter_handler);
+
+ SET_EXPECT(invalid_parameter_handler);
+ errno = 0xdeadbeef;
+ buf[1] = 'a';
+ ret = p_fread_s(buf, 3, 1, 10, f);
+ ok(ret == 0, "fread_s returned %d, expected 0\n", ret);
+ ok(buf[0] == 0, "buf[0] = '%c', expected 0\n", buf[0]);
+ ok(buf[1] == 0, "buf[1] = '%c', expected 0\n", buf[1]);
+ ok(errno == ERANGE, "errno = %d, expected ERANGE\n", errno);
+ CHECK_CALLED(invalid_parameter_handler);
+
+ SET_EXPECT(invalid_parameter_handler);
+ errno = 0xdeadbeef;
+ ret = p_fread_s(buf, 2, 1, 10, f);
+ ok(ret == 0, "fread_s returned %d, expected 0\n", ret);
+ ok(buf[0] == 0, "buf[0] = '%c', expected 0\n", buf[0]);
+ ok(errno == ERANGE, "errno = %d, expected ERANGE\n", errno);
+ CHECK_CALLED(invalid_parameter_handler);
+
+ memset(buf, 'a', sizeof(buf));
+ ret = p_fread_s(buf, sizeof(buf), 3, 10, f);
+ ok(ret==1, "fread_s returned %d, expected 1\n", ret);
+ ok(buf[0] == 'e', "buf[0] = '%c', expected 'e'\n", buf[0]);
+ ok(buf[1] == 's', "buf[1] = '%c', expected 's'\n", buf[1]);
+ ok(buf[2] == 't', "buf[2] = '%c', expected 't'\n", buf[2]);
+ ok(buf[3] == 'a', "buf[3] = '%c', expected 'a'\n", buf[3]);
+ p_fclose(f);
+
+ ok(p_set_invalid_parameter_handler(NULL) == test_invalid_parameter_handler,
+ "Cannot reset invalid parameter handler\n");
+ unlink(test_file);
+}
+
START_TEST(msvcr100)
{
if (!init())
@@ -254,4 +333,5 @@ START_TEST(msvcr100)
test_wmemcpy_s();
test_wmemmove_s();
+ test_fread_s();
}
diff --git a/dlls/msvcr80/msvcr80.spec b/dlls/msvcr80/msvcr80.spec
index e9274f5..2eecb7a 100644
--- a/dlls/msvcr80/msvcr80.spec
+++ b/dlls/msvcr80/msvcr80.spec
@@ -1323,7 +1323,7 @@
@ cdecl fputwc(long ptr) msvcrt.fputwc
@ cdecl fputws(wstr ptr) msvcrt.fputws
@ cdecl fread(ptr long long ptr) msvcrt.fread
-@ stub fread_s
+@ cdecl fread_s(ptr long long long ptr) msvcr100.fread_s
@ cdecl free(ptr) msvcrt.free
@ cdecl freopen(str str ptr) msvcrt.freopen
@ cdecl freopen_s(ptr str str ptr) msvcrt.freopen_s
diff --git a/dlls/msvcr90/msvcr90.spec b/dlls/msvcr90/msvcr90.spec
index 3b18f43..8644692 100644
--- a/dlls/msvcr90/msvcr90.spec
+++ b/dlls/msvcr90/msvcr90.spec
@@ -1324,7 +1324,7 @@
@ cdecl fputwc(long ptr) msvcrt.fputwc
@ cdecl fputws(wstr ptr) msvcrt.fputws
@ cdecl fread(ptr long long ptr) msvcrt.fread
-@ stub fread_s
+@ cdecl fread_s(ptr long long long ptr) msvcr100.fread_s
@ cdecl free(ptr) msvcrt.free
@ cdecl freopen(str str ptr) msvcrt.freopen
@ cdecl freopen_s(ptr str str ptr) msvcrt.freopen_s
diff --git a/include/msvcrt/limits.h b/include/msvcrt/limits.h
index 938da76..d0f058b 100644
--- a/include/msvcrt/limits.h
+++ b/include/msvcrt/limits.h
@@ -38,4 +38,12 @@
#define I64_MAX _I64_MAX
#define UI64_MAX _UI64_MAX
+#ifndef SIZE_MAX
+# ifdef _WIN64
+# define SIZE_MAX UI64_MAX
+# else
+# define SIZE_MAX UINT_MAX
+# endif
+#endif
+
#endif /* __WINE_LIMITS_H */
More information about the wine-cvs
mailing list