Date: Fri, 18 Sep 1998 16:41:42 GMT From: loschert@servint.com To: FreeBSD-gnats-submit@FreeBSD.ORG, freebsd-stable@FreeBSD.ORG Subject: misc/7981: SIGPIPE and write() errors with -libc_r Message-ID: <199809181641.QAA26921@dev.accucount.com>
next in thread | raw e-mail | index | archive | help
>Number: 7981
>Category: misc
>Synopsis: SIGPIPE & write() errors with -libc_r
>Confidential: no
>Severity: serious
>Priority: high
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: doc-bug
>Submitter-Id: current-users
>Arrival-Date: Fri Sep 18 13:50:02 PDT 1998
>Last-Modified:
>Originator: Matt Loschert
>Organization:
ServInt Internet Services
>Release: FreeBSD 2.2.7-STABLE i386
>Environment:
FreeBSD 2.2.7-STABLE (last make world about 3 weeks ago)
>Description:
When linking the thread-safe c library (-libc_r), write()
calls do NOT return -1 and set errno to EPIPE, after writing
to a closed socket. Also, once the write takes place on the
closed socket, the offending process receives a continuous
series of SIGPIPE signals from the system.
>How-To-Repeat:
Compile the following file with the command:
--> gcc -O2 -Wall -o srv srv.c -lc_r
Run the program in the background:
--> ./srv &
Telnet to srv:
--> telnet 0 9999
Type some characters, then quickly issue the telnet disconnect
command (Ctrl-} q).
If the disconnect command is received prior to the server's
response (the server waits 2 seconds), the server will attempt
to write to a now-disconnected socket. When this happens, the
process should receive tons of SIGPIPE's.
Note: This code was adapted from code by John Shapely Gray on
page 297 of his book 'Interprocess Communications in Unix: The
Nooks & Crannies'.
------------------->cut here<------------------------
/*
* filename: srv.c
*/
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define PORT 9999
static char buf[BUFSIZ];
int sig = 0;
extern int errno;
void sig_catch(int);
void *client_handler(void *arg);
int main(void)
{
int serverSkt,
*clientSkt,
clientlength;
struct sockaddr_in
client_address,
server_address;
pthread_t *client_thread;
signal(SIGPIPE, sig_catch);
if((serverSkt=socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("Generate error");
exit(1);
}
bzero(&server_address, sizeof(server_address));
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = htonl(INADDR_ANY);
server_address.sin_port = htons(PORT);
if((bind(serverSkt, (struct sockaddr *) &server_address,
sizeof(server_address))) == -1)
{
perror("bind error");
close(serverSkt);
exit(2);
}
if(listen(serverSkt, 5) < 0) {
perror("listen error");
exit(3);
}
for(;;) {
clientlength = sizeof(client_address);
if((clientSkt = (int *) malloc (sizeof(int))) == NULL) {
perror("malloc error");
exit(4);
}
if((*clientSkt = accept(serverSkt, (struct sockaddr *) &client_address,
&clientlength)) == -1)
{
perror("accept error");
exit(5);
}
if((client_thread = (pthread_t *) malloc (sizeof(pthread_t))) == NULL) {
perror("malloc error");
exit(6);
}
if(pthread_create(client_thread, NULL, &client_handler, clientSkt)) {
perror("pthread_create error");
exit(7);
}
if(pthread_detach(*client_thread)) {
perror("pthread_detach error");
exit(8);
}
free(client_thread);
}
exit(0);
}
void *client_handler(void *arg)
{
int wlen, len, i, skt;
skt = *((int *) arg);
free(arg);
while((len = read(skt, buf, BUFSIZ)) > 0) {
sleep(2);
for(i = 0; i < len; i++)
buf[i] = toupper(buf[i]);
if((wlen = write(skt, buf, len)) <= 0) {
perror("Write failed");
close(skt);
exit(5);
}
printf( "Write(1) len = %d\n", wlen);
if((wlen = write(skt, "", sizeof(""))) <= 0) {
printf("wlen=%d\n", wlen);
perror("Write failed");
close(skt);
exit(5);
}
printf( "Write(2) len = %d\n", wlen);
if (buf[0] == '.') break;
}
close(skt);
exit(0);
}
void sig_catch(int s) {
printf ("Signal %d detected\n", s);
}
------------------->cut here<------------------------
>Fix:
Don't know.
>Audit-Trail:
>Unformatted:
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199809181641.QAA26921>
