Commit 8698bb6c authored by Russ Cox's avatar Russ Cox

runtime: turn "too many EPIPE" into real SIGPIPE

Tested on Linux and OS X, amd64 and 386.

R=r, iant
CC=golang-dev
https://golang.org/cl/4452046
parent 41e5de21
...@@ -10,11 +10,13 @@ import ( ...@@ -10,11 +10,13 @@ import (
"syscall" "syscall"
) )
func sigpipe() // implemented in package runtime
func epipecheck(file *File, e int) { func epipecheck(file *File, e int) {
if e == syscall.EPIPE { if e == syscall.EPIPE {
file.nepipe++ file.nepipe++
if file.nepipe >= 10 { if file.nepipe >= 10 {
panic("os.File Write: caller keeps writing after too many EPIPE errors") sigpipe()
} }
} else { } else {
file.nepipe = 0 file.nepipe = 0
......
...@@ -185,3 +185,10 @@ runtime·resetcpuprofiler(int32 hz) ...@@ -185,3 +185,10 @@ runtime·resetcpuprofiler(int32 hz)
} }
m->profilehz = hz; m->profilehz = hz;
} }
void
os·sigpipe(void)
{
sigaction(SIGPIPE, SIG_DFL, false);
runtime·raisesigpipe();
}
...@@ -33,6 +33,16 @@ TEXT runtime·write(SB),7,$0 ...@@ -33,6 +33,16 @@ TEXT runtime·write(SB),7,$0
INT $0x80 INT $0x80
RET RET
TEXT runtime·raisesigpipe(SB),7,$8
get_tls(CX)
MOVL m(CX), DX
MOVL m_procid(DX), DX
MOVL DX, 0(SP) // thread_port
MOVL $13, 4(SP) // signal: SIGPIPE
MOVL $328, AX // __pthread_kill
INT $0x80
RET
TEXT runtime·mmap(SB),7,$0 TEXT runtime·mmap(SB),7,$0
MOVL $197, AX MOVL $197, AX
INT $0x80 INT $0x80
......
...@@ -195,3 +195,10 @@ runtime·resetcpuprofiler(int32 hz) ...@@ -195,3 +195,10 @@ runtime·resetcpuprofiler(int32 hz)
} }
m->profilehz = hz; m->profilehz = hz;
} }
void
os·sigpipe(void)
{
sigaction(SIGPIPE, SIG_DFL, false);
runtime·raisesigpipe();
}
...@@ -38,6 +38,15 @@ TEXT runtime·write(SB),7,$0 ...@@ -38,6 +38,15 @@ TEXT runtime·write(SB),7,$0
SYSCALL SYSCALL
RET RET
TEXT runtime·raisesigpipe(SB),7,$24
get_tls(CX)
MOVQ m(CX), DX
MOVL $13, DI // arg 1 SIGPIPE
MOVQ m_procid(DX), SI // arg 2 thread_port
MOVL $(0x2000000+328), AX // syscall entry __pthread_kill
SYSCALL
RET
TEXT runtime·setitimer(SB), 7, $0 TEXT runtime·setitimer(SB), 7, $0
MOVL 8(SP), DI MOVL 8(SP), DI
MOVQ 16(SP), SI MOVQ 16(SP), SI
......
...@@ -27,3 +27,5 @@ void runtime·sigaltstack(struct StackT*, struct StackT*); ...@@ -27,3 +27,5 @@ void runtime·sigaltstack(struct StackT*, struct StackT*);
void runtime·sigtramp(void); void runtime·sigtramp(void);
void runtime·sigpanic(void); void runtime·sigpanic(void);
void runtime·setitimer(int32, Itimerval*, Itimerval*); void runtime·setitimer(int32, Itimerval*, Itimerval*);
void runtime·raisesigpipe(void);
...@@ -182,3 +182,10 @@ runtime·resetcpuprofiler(int32 hz) ...@@ -182,3 +182,10 @@ runtime·resetcpuprofiler(int32 hz)
} }
m->profilehz = hz; m->profilehz = hz;
} }
void
os·sigpipe(void)
{
sigaction(SIGPIPE, SIG_DFL, false);
runtime·raisesigpipe();
}
...@@ -60,6 +60,20 @@ TEXT runtime·write(SB),7,$-4 ...@@ -60,6 +60,20 @@ TEXT runtime·write(SB),7,$-4
INT $0x80 INT $0x80
RET RET
TEXT runtime·raisesigpipe(SB),7,$12
// thr_self(&8(SP))
LEAL 8(SP), AX
MOVL AX, 0(SP)
MOVL $432, AX
INT $0x80
// thr_kill(self, SIGPIPE)
MOVL 8(SP), AX
MOVL AX, 0(SP)
MOVL $13, 4(SP)
MOVL $433, AX
INT $0x80
RET
TEXT runtime·notok(SB),7,$0 TEXT runtime·notok(SB),7,$0
MOVL $0xf1, 0xf1 MOVL $0xf1, 0xf1
RET RET
......
...@@ -190,3 +190,10 @@ runtime·resetcpuprofiler(int32 hz) ...@@ -190,3 +190,10 @@ runtime·resetcpuprofiler(int32 hz)
} }
m->profilehz = hz; m->profilehz = hz;
} }
void
os·sigpipe(void)
{
sigaction(SIGPIPE, SIG_DFL, false);
runtime·raisesigpipe();
}
...@@ -65,6 +65,18 @@ TEXT runtime·write(SB),7,$-8 ...@@ -65,6 +65,18 @@ TEXT runtime·write(SB),7,$-8
SYSCALL SYSCALL
RET RET
TEXT runtime·raisesigpipe(SB),7,$16
// thr_self(&8(SP))
LEAQ 8(SP), DI // arg 1 &8(SP)
MOVL $432, AX
SYSCALL
// thr_kill(self, SIGPIPE)
MOVQ 8(SP), DI // arg 1 id
MOVQ $13, SI // arg 2 SIGPIPE
MOVL $433, AX
SYSCALL
RET
TEXT runtime·setitimer(SB), 7, $-8 TEXT runtime·setitimer(SB), 7, $-8
MOVL 8(SP), DI MOVL 8(SP), DI
MOVQ 16(SP), SI MOVQ 16(SP), SI
......
...@@ -8,3 +8,5 @@ struct sigaction; ...@@ -8,3 +8,5 @@ struct sigaction;
void runtime·sigaction(int32, struct sigaction*, struct sigaction*); void runtime·sigaction(int32, struct sigaction*, struct sigaction*);
void runtiem·setitimerval(int32, Itimerval*, Itimerval*); void runtiem·setitimerval(int32, Itimerval*, Itimerval*);
void runtime·setitimer(int32, Itimerval*, Itimerval*); void runtime·setitimer(int32, Itimerval*, Itimerval*);
void runtime·raisesigpipe(void);
...@@ -175,3 +175,10 @@ runtime·resetcpuprofiler(int32 hz) ...@@ -175,3 +175,10 @@ runtime·resetcpuprofiler(int32 hz)
} }
m->profilehz = hz; m->profilehz = hz;
} }
void
os·sigpipe(void)
{
sigaction(SIGPIPE, SIG_DFL, false);
runtime·raisesigpipe();
}
...@@ -30,6 +30,14 @@ TEXT runtime·write(SB),7,$0 ...@@ -30,6 +30,14 @@ TEXT runtime·write(SB),7,$0
INT $0x80 INT $0x80
RET RET
TEXT runtime·raisesigpipe(SB),7,$12
MOVL $224, AX // syscall - gettid
INT $0x80
MOVL AX, 0(SP) // arg 1 tid
MOVL $13, 4(SP) // arg 2 SIGPIPE
MOVL $238, AX // syscall - tkill
INT $0x80
RET
TEXT runtime·setitimer(SB),7,$0-24 TEXT runtime·setitimer(SB),7,$0-24
MOVL $104, AX // syscall - setitimer MOVL $104, AX // syscall - setitimer
......
...@@ -185,3 +185,10 @@ runtime·resetcpuprofiler(int32 hz) ...@@ -185,3 +185,10 @@ runtime·resetcpuprofiler(int32 hz)
} }
m->profilehz = hz; m->profilehz = hz;
} }
void
os·sigpipe(void)
{
sigaction(SIGPIPE, SIG_DFL, false);
runtime·raisesigpipe();
}
...@@ -36,6 +36,15 @@ TEXT runtime·write(SB),7,$0-24 ...@@ -36,6 +36,15 @@ TEXT runtime·write(SB),7,$0-24
SYSCALL SYSCALL
RET RET
TEXT runtime·raisesigpipe(SB),7,$12
MOVL $186, AX // syscall - gettid
SYSCALL
MOVL AX, DI // arg 1 tid
MOVL $13, SI // arg 2 SIGPIPE
MOVL $200, AX // syscall - tkill
SYSCALL
RET
TEXT runtime·setitimer(SB),7,$0-24 TEXT runtime·setitimer(SB),7,$0-24
MOVL 8(SP), DI MOVL 8(SP), DI
MOVQ 16(SP), SI MOVQ 16(SP), SI
......
...@@ -180,3 +180,10 @@ runtime·resetcpuprofiler(int32 hz) ...@@ -180,3 +180,10 @@ runtime·resetcpuprofiler(int32 hz)
} }
m->profilehz = hz; m->profilehz = hz;
} }
void
os·sigpipe(void)
{
sigaction(SIGPIPE, SIG_DFL, false);
runtime·raisesigpipe();
}
...@@ -27,6 +27,8 @@ ...@@ -27,6 +27,8 @@
#define SYS_exit_group (SYS_BASE + 248) #define SYS_exit_group (SYS_BASE + 248)
#define SYS_munmap (SYS_BASE + 91) #define SYS_munmap (SYS_BASE + 91)
#define SYS_setitimer (SYS_BASE + 104) #define SYS_setitimer (SYS_BASE + 104)
#define SYS_gettid (SYS_BASE + 224)
#define SYS_tkill (SYS_BASE + 238)
#define ARM_BASE (SYS_BASE + 0x0f0000) #define ARM_BASE (SYS_BASE + 0x0f0000)
#define SYS_ARM_cacheflush (ARM_BASE + 2) #define SYS_ARM_cacheflush (ARM_BASE + 2)
...@@ -55,6 +57,15 @@ TEXT runtime·exit1(SB),7,$-4 ...@@ -55,6 +57,15 @@ TEXT runtime·exit1(SB),7,$-4
MOVW $1003, R1 MOVW $1003, R1
MOVW R0, (R1) // fail hard MOVW R0, (R1) // fail hard
TEXT runtime·raisesigpipe(SB),7,$-4
MOVW $SYS_gettid, R7
SWI $0
// arg 1 tid already in R0 from gettid
MOVW $13, R1 // arg 2 SIGPIPE
MOVW $SYS_tkill, R7
SWI $0
RET
TEXT runtime·mmap(SB),7,$0 TEXT runtime·mmap(SB),7,$0
MOVW 0(FP), R0 MOVW 0(FP), R0
MOVW 4(FP), R1 MOVW 4(FP), R1
......
...@@ -15,3 +15,5 @@ void runtime·rt_sigaction(uintptr, struct Sigaction*, void*, uintptr); ...@@ -15,3 +15,5 @@ void runtime·rt_sigaction(uintptr, struct Sigaction*, void*, uintptr);
void runtime·sigaltstack(Sigaltstack*, Sigaltstack*); void runtime·sigaltstack(Sigaltstack*, Sigaltstack*);
void runtime·sigpanic(void); void runtime·sigpanic(void);
void runtime·setitimer(int32, Itimerval*, Itimerval*); void runtime·setitimer(int32, Itimerval*, Itimerval*);
void runtime·raisesigpipe(void);
...@@ -138,3 +138,8 @@ runtime·notewakeup(Note *n) ...@@ -138,3 +138,8 @@ runtime·notewakeup(Note *n)
runtime·usemrelease(&n->sema); runtime·usemrelease(&n->sema);
} }
void
os·sigpipe(void)
{
runtime·throw("too many writes on closed pipe");
}
...@@ -378,3 +378,9 @@ runtime·compilecallback(Eface fn, bool cleanstack) ...@@ -378,3 +378,9 @@ runtime·compilecallback(Eface fn, bool cleanstack)
return ret; return ret;
} }
void
os·sigpipe(void)
{
runtime·throw("too many writes on closed pipe");
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment