Subject: kern/2945: [dM] write() -> EINVAL not EPIPE
To: None <gnats-bugs@gnats.netbsd.org>
From: der Mouse <mouse@Rodents.Montreal.QC.CA>
List: netbsd-bugs
Date: 11/15/1996 21:37:08
>Number: 2945
>Category: kern
>Synopsis: [dM] write() -> EINVAL not EPIPE
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people (Kernel Bug People)
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Fri Nov 15 18:50:01 1996
>Last-Modified:
>Originator: der Mouse
>Organization:
Dis-
>Release: 1.2_BETA
>Environment:
Found on NetBSD/sun3 somewhat-pre-1.2 -current (source tree sup
date is July 3rd).
System: NetBSD Twig.Rodents.Montreal.QC.CA 1.2_BETA NetBSD 1.2_BETA (TWIG) #0: Tue Sep 3 00:45:26 EDT 1996 mouse@Twig.Rodents.Montreal.QC.CA:/mouse/sources/working-usr-src/sys/arch/sun3/compile/TWIG sun3
Verified present on NetBSD/hp300, straight off the 1.2
distribution tarballs.
System: NetBSD 1.2 NetBSD 1.2 (GENERIC) #7: Sun Sep 15 16:15:20 PDT 1996 thorpej@basalt:/u3/NetBSD-1.2/src/sys/arch/hp300/compile/GENERIC hp300
>Description:
write() returns EINVAL in circumstances under which I believe
it should be returning EPIPE. Specifically:
Server listen()s for connections
Client connect()s
Client blindly write()s data to the connection
Server read()s one bufferful
Server decides to dump the connection
Server write()s a few bytes to the connection
Server close()s the connection
Client's write gets EINVAL instead of the expected EPIPE
>How-To-Repeat:
Note that the "parent write error" printed is "Invalid argument",
rather than the expected "Broken pipe".
[Twig] 1> cat writebug.c
#include <stdio.h>
#include <errno.h>
#include <signal.h>
#include <unistd.h>
#include <strings.h>
#include <sys/socket.h>
#include <netinet/in.h>
char **argvec;
#define CHK(call) chk((call),#call)
static int chk(int value, const char *txt)
{
if (value < 0)
{ fprintf(stderr,"%s: %s: %s\n",argvec[0],txt,strerror(errno));
exit(1);
}
return(value);
}
static void child(int fd)
{
char buf[10240];
int n;
fprintf(stderr,"%s: child calling read()\n",argvec[0]);
n = read(fd,&buf[0],sizeof(buf));
fprintf(stderr,"%s: child read returned %d\n",argvec[0],n);
fprintf(stderr,"%s: child calling write()\n",argvec[0]);
n = write(fd,"this is a message\n",18);
fprintf(stderr,"%s: child write returned %d\n",argvec[0],n);
close(fd);
sleep(10);
}
static void parent(int fd)
{
int n;
char buf[4096];
sleep(1); /* let child block in read() */
bzero(&buf[0],sizeof(buf));
while (1)
{ fprintf(stderr,"%s: parent calling write()\n",argvec[0]);
n = write(fd,&buf[0],sizeof(buf));
if (n < 0)
{ fprintf(stderr,"%s: parent write error: %s\n",argvec[0],strerror(errno));
exit(1);
}
else
{ fprintf(stderr,"%s: parent write returned %d\n",argvec[0],n);
}
}
}
int main(int, char **);
int main(int ac __attribute__ ((unused)), char **av)
{
int s;
struct sockaddr_in sin;
int sinlen;
int pid;
argvec = av;
signal(SIGPIPE,SIG_IGN);
s = CHK(socket(AF_INET,SOCK_STREAM,0));
bzero(&sin,sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = 0;
CHK(bind(s,(struct sockaddr *)&sin,sizeof(sin)));
sinlen = sizeof(sin);
CHK(getsockname(s,(struct sockaddr *)&sin,&sinlen));
CHK(listen(s,3));
pid = CHK(fork());
if (pid == 0)
{ close(s);
s = CHK(socket(AF_INET,SOCK_STREAM,0));
CHK(connect(s,(struct sockaddr *)&sin,sizeof(sin)));
child(s);
}
else
{ sinlen = sizeof(sin);
s = CHK(accept(s,(struct sockaddr *)&sin,&sinlen));
parent(s);
}
exit(0);
}
[Twig] 2> cc -o writebug writebug.c
[Twig] 3> ktrace -i ./writebug
./writebug: child calling read()
./writebug: parent calling write()
./writebug: child read returned 2048
./writebug: child calling write()
./writebug: child write returned 18
./writebug: parent write returned 4096
./writebug: parent calling write()
./writebug: parent write error: Invalid argument
[Twig] 4> kdump
29314 ktrace RET ktrace 0
29314 ktrace CALL execve(0xdfffa9e,0xdfffa30,0xdfffa38)
29314 ktrace NAMI "./writebug"
29314 writebug EMUL "netbsd"
29314 writebug RET execve 0
29314 writebug CALL open(0x20b8,0,0)
29314 writebug NAMI "/usr/libexec/ld.so"
29314 writebug RET open 3
29314 writebug CALL read(0x3,0xdfff9f8,0x20)
29314 writebug GIO fd 3 read 32 bytes
"\M-@\M^G\^A\v\0\0\240\0\0\0 \0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\0\0\0\0"
29314 writebug RET read 32/0x20
29314 writebug CALL mmap(0,0xc000,0x5,0x4,0x3,0,0,0)
29314 writebug RET mmap 67239936/0x4020000
29314 writebug CALL mmap(0x402a000,0x2000,0x3,0x14,0x3,0,0,0xa000)
29314 writebug RET mmap 67280896/0x402a000
29314 writebug CALL getuid
29314 writebug RET getuid 999/0x3e7
29314 writebug CALL geteuid
29314 writebug RET geteuid 999/0x3e7
29314 writebug CALL getgid
29314 writebug RET getgid 0
29314 writebug CALL getegid
29314 writebug RET getegid 0
29314 writebug CALL __sysctl(0xdfff91c,0x2,0x402ba8c,0xdfff924,0,0)
29314 writebug RET __sysctl 0
29314 writebug CALL mmap(0,0x8000,0x3,0x1004,0xffffffff,0,0,0)
29314 writebug RET mmap 67371008/0x4040000
29314 writebug CALL mmap(0,0xa000,0x3,0x1004,0xffffffff,0,0,0)
29314 writebug RET mmap 67502080/0x4060000
29314 writebug CALL open(0x402153a,0,0)
29314 writebug NAMI "/var/run/ld.so.hints"
29314 writebug RET open 4
29314 writebug CALL mmap(0,0x2000,0x1,0x4,0x4,0,0,0)
29314 writebug RET mmap 67633152/0x4080000
29314 writebug CALL open(0x4080322,0,0)
29314 writebug NAMI "/usr/lib/libc.so.12.5"
29314 writebug RET open 5
29314 writebug CALL read(0x5,0xdfff94c,0x20)
29314 writebug GIO fd 5 read 32 bytes
"\M-@\M^G\^A\v\0\^D\M-@\0\0\0\M^@\0\0\0\M^G$\0\0001\M-`\0\0\0 \0\0\0\0\
\0\0\0\0"
29314 writebug RET read 32/0x20
29314 writebug CALL mmap(0,0x5c724,0x5,0x4,0x5,0,0,0)
29314 writebug RET mmap 67764224/0x40a0000
29314 writebug CALL mprotect(0x40ec000,0x8000,0x7)
29314 writebug RET mprotect 0
29314 writebug CALL mmap(0x40f4000,0x8724,0x7,0x1014,0xffffffff,0,0,0)
29314 writebug RET mmap 68108288/0x40f4000
29314 writebug CALL close(0x5)
29314 writebug RET close 0
29314 writebug CALL munmap(0x4080000,0x2000)
29314 writebug RET munmap 0
29314 writebug CALL close(0x4)
29314 writebug RET close 0
29314 writebug CALL close(0x3)
29314 writebug RET close 0
29314 writebug CALL sigaction(0xd,0xdfff9d8,0xdfff9cc)
29314 writebug RET sigaction 0
29314 writebug CALL socket(0x2,0x1,0)
29314 writebug RET socket 3
29314 writebug CALL bind(0x3,0xdfff9fc,0x10)
29314 writebug RET bind 0
29314 writebug CALL getsockname(0x3,0xdfff9fc,0xdfff9f8)
29314 writebug RET getsockname 0
29314 writebug CALL listen(0x3,0x3)
29314 writebug RET listen 0
29314 writebug CALL fork
29314 writebug RET fork 29315/0x7283
29314 writebug CALL accept(0x3,0xdfff9fc,0xdfff9f8)
29315 writebug RET fork 0
29315 writebug CALL close(0x3)
29315 writebug RET close 0
29315 writebug CALL socket(0x2,0x1,0)
29315 writebug RET socket 3
29315 writebug CALL connect(0x3,0xdfff9fc,0x10)
29314 writebug RET accept 4
29314 writebug CALL sigprocmask(0x1,0x2000)
29314 writebug RET sigprocmask 0
29314 writebug CALL sigaction(0xe,0xdffe9ac,0xdffe9a0)
29314 writebug RET sigaction 0
29314 writebug CALL setitimer(0,0xdffe9c8,0xdffe9b8)
29314 writebug RET setitimer 0
29314 writebug CALL sigsuspend(0)
29315 writebug RET connect 0
29315 writebug CALL write(0x2,0xdffcb28,0x21)
29315 writebug GIO fd 2 wrote 33 bytes
"./writebug: child calling read()
"
29315 writebug RET write 33/0x21
29315 writebug CALL read(0x3,0xdffd1e8,0x2800)
29314 writebug PSIG SIGALRM caught handler=0x40c0226 mask=0x2000 code=0x0
29314 writebug RET sigsuspend -1 errno 4 Interrupted system call
29314 writebug CALL sigreturn(0xdffe954)
29314 writebug RET sigreturn JUSTRETURN
29314 writebug CALL sigprocmask(0x3,0)
29314 writebug RET sigprocmask 8192/0x2000
29314 writebug CALL sigaction(0xe,0xdffe9a0,0)
29314 writebug RET sigaction 0
29314 writebug CALL setitimer(0,0xdffe9b8,0xdffe9c8)
29314 writebug RET setitimer 0
29314 writebug CALL write(0x2,0xdffe328,0x23)
29314 writebug GIO fd 2 wrote 35 bytes
"./writebug: parent calling write()
"
29314 writebug RET write 35/0x23
29314 writebug CALL write(0x4,0xdffe9e4,0x1000)
29314 writebug GIO fd 4 wrote 4096 bytes
[4096 \0s deleted]
29315 writebug GIO fd 3 read 2048 bytes
[2048 \0s deleted]
29315 writebug RET read 2048/0x800
29315 writebug CALL write(0x2,0xdffcb24,0x25)
29315 writebug GIO fd 2 wrote 37 bytes
"./writebug: child read returned 2048
"
29315 writebug RET write 37/0x25
29315 writebug CALL write(0x2,0xdffcb28,0x22)
29315 writebug GIO fd 2 wrote 34 bytes
"./writebug: child calling write()
"
29315 writebug RET write 34/0x22
29315 writebug CALL write(0x3,0x2803,0x12)
29315 writebug GIO fd 3 wrote 18 bytes
"this is a message
"
29315 writebug RET write 18/0x12
29315 writebug CALL write(0x2,0xdffcb24,0x24)
29315 writebug GIO fd 2 wrote 36 bytes
"./writebug: child write returned 18
"
29315 writebug RET write 36/0x24
29315 writebug CALL close(0x3)
29315 writebug RET close 0
29315 writebug CALL sigprocmask(0x1,0x2000)
29315 writebug RET sigprocmask 0
29315 writebug CALL sigaction(0xe,0xdffd1ac,0xdffd1a0)
29315 writebug RET sigaction 0
29315 writebug CALL setitimer(0,0xdffd1c8,0xdffd1b8)
29315 writebug RET setitimer 0
29315 writebug CALL sigsuspend(0)
29314 writebug RET write 4096/0x1000
29314 writebug CALL write(0x2,0xdffe324,0x27)
29314 writebug GIO fd 2 wrote 39 bytes
"./writebug: parent write returned 4096
"
29314 writebug RET write 39/0x27
29314 writebug CALL write(0x2,0xdffe328,0x23)
29314 writebug GIO fd 2 wrote 35 bytes
"./writebug: parent calling write()
"
29314 writebug RET write 35/0x23
29314 writebug CALL write(0x4,0xdffe9e4,0x1000)
29314 writebug RET write -1 errno 22 Invalid argument
29314 writebug CALL open(0xdffe5a4,0,0x40c9ec7)
29314 writebug NAMI "/usr/share/nls/C/libc.cat"
29314 writebug RET open 5
29314 writebug CALL fstat(0x5,0xdffe528)
29314 writebug RET fstat 0
29314 writebug CALL mmap(0,0xe5a,0x1,0x1,0x5,0,0,0)
29314 writebug RET mmap 67633152/0x4080000
29314 writebug CALL close(0x5)
29314 writebug RET close 0
29314 writebug CALL __sysctl(0xdffe4e0,0x2,0x40fc720,0xdffe4e8,0,0)
29314 writebug RET __sysctl 0
29314 writebug CALL break(0x426c)
29314 writebug RET break 0
29314 writebug CALL break(0x5ffc)
29314 writebug RET break 0
29314 writebug CALL break(0x7ffc)
29314 writebug RET break 0
29314 writebug CALL munmap(0x4080000,0xe5a)
29314 writebug RET munmap 0
29314 writebug CALL write(0x2,0xdffe324,0x31)
29314 writebug GIO fd 2 wrote 49 bytes
"./writebug: parent write error: Invalid argument
"
29314 writebug RET write 49/0x31
29314 writebug CALL exit(0x1)
[Twig] 5>
>Fix:
Darned if I know. At present I have no idea why it's happening
to begin with.
der Mouse
mouse@rodents.montreal.qc.ca
01 EE 31 F6 BB 0C 34 36 00 F3 7C 5A C1 A0 67 1D
>Audit-Trail:
>Unformatted: