diff options
author | Tamar Christina <tamar@zhox.com> | 2016-05-19 21:48:53 +0200 |
---|---|---|
committer | Tamar Christina <tamar@zhox.com> | 2016-05-19 21:50:18 +0200 |
commit | 1ee47c1bfa35c7be435adaec5c1fa9ec92cc776d (patch) | |
tree | 847fa95c9660bab533ede96135a43d799fadeb6d /libraries/base/System/Posix | |
parent | a88bb1b1518389817583290acaebfd6454aa3cec (diff) | |
download | haskell-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.hs | 41 |
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. -} |