Re: PROBLEM: Sending mail-attachment > 45k with Netscape via sendmail hangs

Alan Curry (pacman-kernel@cqc.com)
Thu, 25 Feb 1999 16:45:47 -0500 (EST)


Romano Giannetti writes the following:
>I tried to change the program to simply use a pipe, and it seems it
>blocks in the select too. I hope I did it right, I am not so good in
>unix hacking... attached it goes.

I see a problem immediately with this program: you forgot to close the unused
ends of the pipe after forking. That could explain why it hangs after you
thinkg you've closed the writing end. The reader process has an unused copy
of the writing end of the pipe, so the reading end will block on
select-for-read because there is still the possibility of writes happening.

I cleaned up your program and it behaves as expected for me, but I'm not on
kernel 2.2.2 yet.

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/time.h>
#include <signal.h>

#define READ_SIZE 15

static char buffer[READ_SIZE];

int pipe_fd[2];

#define p_write pipe_fd[1]
#define p_read pipe_fd[0]

static int client(void)
{
int sock, flgs, len, cnt;
fd_set rfds;

sock=p_read;
close(p_write);
flgs = fcntl(sock, F_GETFL, 0);
fcntl(sock, F_SETFL, flgs|O_NONBLOCK);

cnt = 0;

do
{
FD_ZERO(&rfds);
FD_SET(sock, &rfds);
if(select(sock + 1, &rfds, NULL, NULL, NULL) <= 0)
{ perror("select()"); exit(1); }

len = read(sock, buffer, READ_SIZE);
if(len > 0)
cnt += len;

printf("cnt=%d\n",cnt);

} while(len>0);

close(sock);
printf("Got %d bytes.\nConnection closed\n", cnt);


return 0;
}

#define WRITE_SIZE 1585

static const char str[WRITE_SIZE];

static void sigint(int s)
{
(void)s;
printf("***SIGINT\n");
fflush(stdout);
close(p_write);
close(p_read);
exit(0);
}
static void sigpipe(int s)
{
(void)s;
printf("***SIGPIPE\n");
fflush(stdout);
close(p_write);
close(p_read);
exit(0);
}

static int serv(void)
{
int sock;
int i, size, written, flgs;
const char *ptr;
fd_set wfds;

sock=p_write;
close(p_read);


flgs = fcntl(sock, F_GETFL, 0);
fcntl(sock, F_SETFL, flgs|O_NONBLOCK);

printf("sending %d bytes of data...\n",3200*sizeof(str));
for(i = 0; i < 3200; i++)
{
size = sizeof(str);
ptr = str;
while(size)
{
FD_ZERO(&wfds);
FD_SET(sock, &wfds);
if(select(sock+1, NULL, &wfds, NULL, NULL) < 0)
{ perror("select()"); abort(); }

if((written = write(sock, ptr, size)) < 0)
{ perror("write()"); abort(); }

size -= written;
ptr += written;
}
}

printf("ready, sent %d bytes of data\n",3200*sizeof(str));
fflush(stdout);
close(sock);
exit(0);
}

int main(void) {

int pid;
pipe(pipe_fd);
signal(SIGINT, sigint);
signal(SIGPIPE, sigpipe);

pid=fork();
if (pid<0) {
perror("Main:");
exit(1);
}
if (pid==0) {
serv();
} else {
client();
}
return 0;
}

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/