Messages in this thread | | | From | "Alan Curry" <> | Subject | Re: PROBLEM: Sending mail-attachment > 45k with Netscape via sendmail hangs | Date | 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/
| |