summaryrefslogtreecommitdiff
path: root/libraries/base/System/Posix
diff options
context:
space:
mode:
authorTamar Christina <tamar@zhox.com>2016-05-19 21:48:53 +0200
committerTamar Christina <tamar@zhox.com>2016-05-19 21:50:18 +0200
commit1ee47c1bfa35c7be435adaec5c1fa9ec92cc776d (patch)
tree847fa95c9660bab533ede96135a43d799fadeb6d /libraries/base/System/Posix
parenta88bb1b1518389817583290acaebfd6454aa3cec (diff)
downloadhaskell-1ee47c1bfa35c7be435adaec5c1fa9ec92cc776d.tar.gz
Use the correct return type for Windows' send()/recv() (Fix #12010)
Summary: They return signed 32 bit ints on Windows, even on a 64 bit OS, rather than Linux's 64 bit ssize_t. This means when recv() returned -1 to signal an error we thought it was 4294967295. It was converted to an int, -1 and the buffer was memcpy'd which caused a segfault. Other bad stuff happened with send()s. See also note CSsize in System.Posix.Internals. Add a test for #12010 Test Plan: - GHC testsuite (T12010) - http-conduit test (https://github.com/snoyberg/http-client/issues/191) Reviewers: austin, hvr, bgamari, Phyx Reviewed By: Phyx Subscribers: thomie Differential Revision: https://phabricator.haskell.org/D2170 GHC Trac Issues: #12010
Diffstat (limited to 'libraries/base/System/Posix')
-rw-r--r--libraries/base/System/Posix/Internals.hs41
1 files changed, 20 insertions, 21 deletions
diff --git a/libraries/base/System/Posix/Internals.hs b/libraries/base/System/Posix/Internals.hs
index 66e9304d56..630f251669 100644
--- a/libraries/base/System/Posix/Internals.hs
+++ b/libraries/base/System/Posix/Internals.hs
@@ -404,24 +404,24 @@ foreign import ccall unsafe "HsBase.h _dup2"
foreign import ccall unsafe "HsBase.h _isatty"
c_isatty :: CInt -> IO CInt
--- See Note: CSsize
+-- See Note: Windows types
foreign import capi unsafe "HsBase.h _read"
- c_read :: CInt -> Ptr Word8 -> CSize -> IO CSsize
+ c_read :: CInt -> Ptr Word8 -> CUInt -> IO CInt
--- See Note: CSsize
+-- See Note: Windows types
foreign import capi safe "HsBase.h _read"
- c_safe_read :: CInt -> Ptr Word8 -> CSize -> IO CSsize
+ c_safe_read :: CInt -> Ptr Word8 -> CUInt -> IO CInt
foreign import ccall unsafe "HsBase.h _umask"
c_umask :: CMode -> IO CMode
--- See Note: CSsize
+-- See Note: Windows types
foreign import capi unsafe "HsBase.h _write"
- c_write :: CInt -> Ptr Word8 -> CSize -> IO CSsize
+ c_write :: CInt -> Ptr Word8 -> CUInt -> IO CInt
--- See Note: CSsize
+-- See Note: Windows types
foreign import capi safe "HsBase.h _write"
- c_safe_write :: CInt -> Ptr Word8 -> CSize -> IO CSsize
+ c_safe_write :: CInt -> Ptr Word8 -> CUInt -> IO CInt
foreign import ccall unsafe "HsBase.h _unlink"
c_unlink :: CString -> IO CInt
@@ -462,22 +462,22 @@ foreign import ccall unsafe "HsBase.h dup2"
foreign import ccall unsafe "HsBase.h isatty"
c_isatty :: CInt -> IO CInt
--- See Note: CSsize
+-- See Note: Windows types
foreign import capi unsafe "HsBase.h read"
c_read :: CInt -> Ptr Word8 -> CSize -> IO CSsize
--- See Note: CSsize
+-- See Note: Windows types
foreign import capi safe "HsBase.h read"
c_safe_read :: CInt -> Ptr Word8 -> CSize -> IO CSsize
foreign import ccall unsafe "HsBase.h umask"
c_umask :: CMode -> IO CMode
--- See Note: CSsize
+-- See Note: Windows types
foreign import capi unsafe "HsBase.h write"
c_write :: CInt -> Ptr Word8 -> CSize -> IO CSsize
--- See Note: CSsize
+-- See Note: Windows types
foreign import capi safe "HsBase.h write"
c_safe_write :: CInt -> Ptr Word8 -> CSize -> IO CSsize
@@ -619,14 +619,13 @@ foreign import capi unsafe "stdio.h value SEEK_SET" sEEK_SET :: CInt
foreign import capi unsafe "stdio.h value SEEK_END" sEEK_END :: CInt
{-
-Note: CSsize
-
-On Win64, ssize_t is 64 bit, but functions like read return 32 bit
-ints. The CAPI wrapper means the C compiler takes care of doing all
-the necessary casting.
-
-When using ccall instead, when the functions failed with -1, we thought
-they were returning with 4294967295, and so didn't throw an exception.
-This lead to a segfault in echo001(ghci).
+Note: Windows types
+
+Windows' _read and _write have types that differ from POSIX. They take an
+unsigned int for lengh and return a signed int where POSIX uses size_t and
+ssize_t. Those are different on x86_64 and equivalent on x86. We import them
+with the types in Microsoft's documentation which means that c_read,
+c_safe_read, c_write and c_safe_write have different Haskell types depending on
+the OS.
-}