Ticket #1114 (closed bug: invalid)

Opened 6 years ago

Last modified 6 years ago

Socket code dies with SIGPIPE

Reported by: guest Owned by:
Priority: normal Milestone: 6.6.1
Component: hslibs/net Version: 6.6
Keywords: Cc:
Operating System: Linux Architecture: x86
Type of failure: Difficulty: Unknown
Test Case: Blocked By:
Blocking: Related Tickets:

Description

GHC socket / IO handle code dies with SIGPIPE.

Debian Etch

$ uname -a
Linux alien 2.6.19.1y #7 Mon Dec 25 20:48:36 EET 2006 i686 GNU/Linux

$ cat /etc/debian_version 
4.0

$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 6.6

Test program and strace output are here:

 http://linux.ee/~mzz/ghcpipebug/

run: tttd
        strace ./tttd &
        sleep 1
        echo -n | nc -q 0 127.0.0.1 3372; echo -n | nc -q 0 127.0.0.1 3372
        sleep 1

tttd: tttd.hs
        ghc -o $@ $+ -package network

clean:
        rm -f tttd *.hi *.o
import Control.Concurrent
import Network
import System.IO

-- it won't SIGPIPE, when you comment second hPrint
player h hOther otherTh = evil >> hClose h
    where evil = hPrint h 13 >> hPrint h 42

doAccept sock =
     do (h1, _, _) <- accept sock
        (h2, _, _) <- accept sock
        hSetBuffering h1 LineBuffering
        hSetBuffering h2 LineBuffering
        forkIO $ myThreadId >>= forkIO . player h2 h1 >>= player h1 h2
        threadDelay 500000
        hPutStrLn stderr "OK?"

main = withSocketsDo $ listenOn (PortNumber $ fromIntegral 3372) >>= doAccept
select(0, [], [], NULL, {0, 0})         = 0 (Timeout)
write(4, "13\n", 3)                     = 3
gettimeofday({1169512958, 393628}, NULL) = 0
select(0, [], [], NULL, {0, 0})         = 0 (Timeout)
write(5, "13\n", 3)                     = 3
write(5, "42\n", 3)                     = 3
close(5)                                = 0
gettimeofday({1169512958, 393914}, NULL) = 0
select(0, [], [], NULL, {0, 0})         = 0 (Timeout)
write(4, "42\n", 3)                     = -1 EPIPE (Broken pipe)
--- SIGPIPE (Broken pipe) @ 0 (0) ---
+++ killed by SIGPIPE +++
Process 3541 detached

Change History

Changed 6 years ago by guest

Simpler self-contained test case.

import Control.Concurrent
import System.IO
import Network

port = PortNumber $ fromIntegral 1234

main = withSocketsDo $
     do sock <- listenOn port
        forkIO $ connectTo "127.0.0.1" port >>= hClose
        (h, _, _) <- accept sock
        threadDelay 300000 -- ensure that close happens in connecting thread
        hPutChar h '1'
        hFlush h -- two separate writes are needed
        hPutChar h '2'
        hClose h -- this actually does second flush and gets SIGPIPE
        hPutStrLn stderr "OK?" -- we don't get here
select(0, [], [], NULL, {0, 0})         = 0 (Timeout)
gettimeofday({1169519318, 500011}, NULL) = 0
write(4, "1", 1)                        = 1
write(4, "2", 1)                        = -1 EPIPE (Broken pipe)
--- SIGPIPE (Broken pipe) @ 0 (0) ---
+++ killed by SIGPIPE +++
Process 4072 detached

Changed 6 years ago by guest

From write (2) manpage:

EPIPE

fd is connected to a pipe or socket whose reading end is closed. When this happens the writing process will also receive a SIGPIPE signal. (Thus, the write return value is seen only if the program catches, blocks or ignores this signal.)

and send (2) manpage:

ssize_t send(int s, const void *buf, size_t len, int flags);
...
The flags parameter is the bitwise OR of zero or more of the following flags.
...
MSG_NOSIGNAL

Requests not to send SIGPIPE on errors on stream oriented sockets when the other end breaks the connection. The EPIPE error is still returned.

...
EPIPE

The local end has been shut down on a connection oriented socket. In this case the process will also receive a SIGPIPE unless MSG_NOSIGNAL is set.

Changed 6 years ago by igloo

  • milestone set to 6.6.1

Changed 6 years ago by simonmar

  • status changed from new to closed
  • resolution set to invalid

Not a bug: this is the correct (although perhaps unexpected) behaviour. It's documented in the docs for the Network module.

Note: See TracTickets for help on using tickets.