msvcrt: add support for _chsize_s (try #3)

Mike Koss morphiend at gmail.com
Fri Oct 25 21:58:06 CDT 2013


This patch adds the _chsize_s() to the mscvrt and corresponding mscvr*s.
Incorporates previous feedback and now includes an updated test file.

---
 dlls/msvcr100/msvcr100.spec |  2 +-
 dlls/msvcr110/msvcr110.spec |  2 +-
 dlls/msvcr80/msvcr80.spec   |  2 +-
 dlls/msvcr90/msvcr90.spec   |  2 +-
 dlls/msvcrt/file.c          | 63
+++++++++++++++++++++++++++++++++++++++++++++
 dlls/msvcrt/msvcrt.spec     |  2 +-
 dlls/msvcrt/tests/file.c    | 37 ++++++++++++++++++++++++++
 7 files changed, 105 insertions(+), 5 deletions(-)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.winehq.org/pipermail/wine-patches/attachments/20131025/62e61376/attachment.html>
-------------- next part --------------
From 90254bf4fc079a98a8bbe56faa63c8e547fd4741 Mon Sep 17 00:00:00 2001
From: Mike Koss <morphiend at gmail.com>
Date: Fri, 25 Oct 2013 22:54:12 -0400
Subject: Added _chsize_s support and corresponding test

---
 dlls/msvcr100/msvcr100.spec |  2 +-
 dlls/msvcr110/msvcr110.spec |  2 +-
 dlls/msvcr80/msvcr80.spec   |  2 +-
 dlls/msvcr90/msvcr90.spec   |  2 +-
 dlls/msvcrt/file.c          | 63 +++++++++++++++++++++++++++++++++++++++++++++
 dlls/msvcrt/msvcrt.spec     |  2 +-
 dlls/msvcrt/tests/file.c    | 37 ++++++++++++++++++++++++++
 7 files changed, 105 insertions(+), 5 deletions(-)

diff --git a/dlls/msvcr100/msvcr100.spec b/dlls/msvcr100/msvcr100.spec
index 646137d..eaad8fe 100644
--- a/dlls/msvcr100/msvcr100.spec
+++ b/dlls/msvcr100/msvcr100.spec
@@ -725,7 +725,7 @@
 @ cdecl -arch=i386 -norelay _chkesp() msvcrt._chkesp
 @ cdecl _chmod(str long) msvcrt._chmod
 @ cdecl _chsize(long long) msvcrt._chsize
-@ stub _chsize_s
+@ cdecl _chsize_s(long int64) msvcrt._chsize_s
 @ cdecl _clearfp() msvcrt._clearfp
 @ cdecl _close(long) msvcrt._close
 @ cdecl _commit(long) msvcrt._commit
diff --git a/dlls/msvcr110/msvcr110.spec b/dlls/msvcr110/msvcr110.spec
index a704d1a..d909719 100644
--- a/dlls/msvcr110/msvcr110.spec
+++ b/dlls/msvcr110/msvcr110.spec
@@ -1073,7 +1073,7 @@
 @ cdecl -arch=i386 -norelay _chkesp() msvcrt._chkesp
 @ cdecl _chmod(str long) msvcrt._chmod
 @ cdecl _chsize(long long) msvcrt._chsize
-@ stub _chsize_s
+@ cdecl _chsize_s(long int64) msvcrt._chsize_s
 @ cdecl _clearfp() msvcrt._clearfp
 @ cdecl _close(long) msvcrt._close
 @ cdecl _commit(long) msvcrt._commit
diff --git a/dlls/msvcr80/msvcr80.spec b/dlls/msvcr80/msvcr80.spec
index 0a0adf6..697936c 100644
--- a/dlls/msvcr80/msvcr80.spec
+++ b/dlls/msvcr80/msvcr80.spec
@@ -389,7 +389,7 @@
 @ cdecl -arch=i386 -norelay _chkesp() msvcrt._chkesp
 @ cdecl _chmod(str long) msvcrt._chmod
 @ cdecl _chsize(long long) msvcrt._chsize
-@ stub _chsize_s
+@ cdecl _chsize_s(long int64) msvcrt._chsize_s
 @ cdecl _clearfp() msvcrt._clearfp
 @ cdecl _close(long) msvcrt._close
 @ cdecl _commit(long) msvcrt._commit
diff --git a/dlls/msvcr90/msvcr90.spec b/dlls/msvcr90/msvcr90.spec
index 382a52e..ca2503f 100644
--- a/dlls/msvcr90/msvcr90.spec
+++ b/dlls/msvcr90/msvcr90.spec
@@ -372,7 +372,7 @@
 @ cdecl -arch=i386 -norelay _chkesp() msvcrt._chkesp
 @ cdecl _chmod(str long) msvcrt._chmod
 @ cdecl _chsize(long long) msvcrt._chsize
-@ stub _chsize_s
+@ cdecl _chsize_s(long int64) msvcrt._chsize_s
 @ cdecl _clearfp() msvcrt._clearfp
 @ cdecl _close(long) msvcrt._close
 @ cdecl _commit(long) msvcrt._commit
diff --git a/dlls/msvcrt/file.c b/dlls/msvcrt/file.c
index 89ac94c..bcf9c71 100644
--- a/dlls/msvcrt/file.c
+++ b/dlls/msvcrt/file.c
@@ -1295,6 +1295,69 @@ int CDECL MSVCRT__chsize(int fd, MSVCRT_long size)
 }
 
 /*********************************************************************
+ *		_chsize_s (MSVCRT.@)
+ */
+int CDECL MSVCRT__chsize_s(int fd, __int64 size)
+{
+    __int64 cur, pos;
+    HANDLE handle;
+    int ret = 0;
+
+    TRACE("(fd=%d, size=%lld)\n", fd, size);
+
+    LOCK_FILES();
+
+    handle = msvcrt_fdtoh(fd);
+    if (!MSVCRT_CHECK_PMT_ERR(handle != INVALID_HANDLE_VALUE, MSVCRT_EBADF) ||
+            !MSVCRT_CHECK_PMT_ERR(size >= 0, MSVCRT_EINVAL))
+    {
+        ret = *MSVCRT__errno();
+    }
+    else
+    {
+        /* save the current file pointer */
+        cur = MSVCRT__lseeki64(fd, 0, SEEK_CUR);
+        if (cur < 0)
+        {
+            msvcrt_set_errno(GetLastError());
+            ret = *MSVCRT__errno();
+        }
+        else
+        {
+            /* lseeki64 uses SetFilePointer which uses 
+               NtSetInformationFile which uses ftruncate() to extend 
+               the file size. This will init bytes to 0, and thereby
+               meet the MSDN doc for _chsize_s() */
+            pos = MSVCRT__lseeki64(fd, size, SEEK_SET);
+            if (pos < 0)
+            {
+                msvcrt_set_errno(GetLastError());
+                ret = *MSVCRT__errno();
+            }
+            else
+            {
+                ret = SetEndOfFile(handle);
+                if (!ret)
+                {
+                    msvcrt_set_errno(GetLastError());
+                    ret = *MSVCRT__errno();
+                }
+                else
+                {
+                    ret = 0;
+                }
+
+                /* restore the file pointer */
+                MSVCRT__lseeki64(fd, cur, SEEK_SET);
+            }
+        }
+    }
+
+    UNLOCK_FILES();
+    return ret;
+}
+
+/*********************************************************************
  *		clearerr (MSVCRT.@)
  */
 void CDECL MSVCRT_clearerr(MSVCRT_FILE* file)
diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec
index 5e57aae..a87e72f 100644
--- a/dlls/msvcrt/msvcrt.spec
+++ b/dlls/msvcrt/msvcrt.spec
@@ -356,7 +356,7 @@
 @ cdecl -arch=i386 -norelay _chkesp()
 @ cdecl _chmod(str long) MSVCRT__chmod
 @ cdecl _chsize(long long) MSVCRT__chsize
-# stub _chsize_s(long int64)
+@ cdecl _chsize_s(long int64) MSVCRT__chsize_s
 # stub _chvalidator(long long)
 # stub _chvalidator_l(ptr long long)
 @ cdecl _clearfp()
diff --git a/dlls/msvcrt/tests/file.c b/dlls/msvcrt/tests/file.c
index 2d2399a..71d7acf 100644
--- a/dlls/msvcrt/tests/file.c
+++ b/dlls/msvcrt/tests/file.c
@@ -1548,6 +1548,42 @@ static void test_chsize( void )
     free( tempfile );
 }
 
+static void test_chsize_s( void )
+{
+    int fd;
+    LONG cur, pos, count;
+    char temptext[] = "012345678";
+    char *tempfile = _tempnam( ".", "tst" );
+    
+    ok( tempfile != NULL, "Couldn't create test file: %s\n", tempfile );
+
+    fd = _open( tempfile, _O_CREAT|_O_TRUNC|_O_RDWR, _S_IREAD|_S_IWRITE );
+    ok( fd > 0, "Couldn't open test file\n" );
+
+    count = _write( fd, temptext, sizeof(temptext) );
+    ok( count > 0, "Couldn't write to test file\n" );
+
+    /* get current file pointer */
+    cur = _lseek( fd, 0, SEEK_CUR );
+
+    /* make the file smaller */
+    ok( _chsize_s( fd, sizeof(temptext) / 2 ) == 0, "_chsize_s() failed\n" );
+
+    pos = _lseek( fd, 0, SEEK_CUR );
+    ok( cur == pos, "File pointer changed from: %d to: %d\n", cur, pos );
+    ok( _filelength( fd ) == sizeof(temptext) / 2, "Wrong file size\n" );
+
+    /* enlarge the file */
+    ok( _chsize_s( fd, sizeof(temptext) * 2 ) == 0, "_chsize_s() failed\n" ); 
+
+    pos = _lseek( fd, 0, SEEK_CUR );
+    ok( cur == pos, "File pointer changed from: %d to: %d\n", cur, pos );
+    ok( _filelength( fd ) == sizeof(temptext) * 2, "Wrong file size\n" );
+
+    _close( fd );
+    _unlink( tempfile );
+    free( tempfile );
+}
 static void test_fopen_fclose_fcloseall( void )
 {
     char fname1[] = "empty1";
@@ -2187,6 +2223,7 @@ START_TEST(file)
     test_file_inherit(arg_v[0]);
     test_file_write_read();
     test_chsize();
+    test_chsize_s();
     test_stat();
     test_unlink();
 
-- 
1.8.1.2


More information about the wine-patches mailing list