Hello cywin guru,
Maybe you can help me with the following problem. We are running Cygwin version 1.3.10 on Windows NT. We use sigaction to redirect the SIGIO signal to our own signal handler in a client/server app. When running several processes of the same client program in the background, a couple of them seem to hang. It is interesting that this problem does not surface when we have all those processes running in the foreground or when we start them using "cmd start /high ..." Please find attached the relevant code for reproducing the problem. It is a client program that tries to connect to a telnetd. It expects the machine name where telnetd is running as well as the repeat count for the send loop. I reproduced the problem as follows 1. opened an xterm with a bash 2. in the xterm I typed the following for i in 1 2 3 do ./a.exe localhost 300 & done The result was that one process did well, but the other two hanged. Is this behavior related to a known CYGWIN problem? Do you think we can change our code in some way to avoid this problem? We will greatly appreciate your expert advice on this matter. Greetings, Ivan
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <netdb.h> #include <netinet/in.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/ioctl.h> #include <string.h> #include <signal.h> int global_int; void handle_signal(int a) { global_int = 1; } int set_mode(int socknum, int mode) { int real_mode; int flags, yes = 1; // yes actually is needed for CYGWIN real_mode = mode & (FASYNC + FNDELAY); flags = fcntl (socknum, F_GETFL); if (flags == -1) { perror("GETFL failed"); exit(0); } #ifdef __CYGWIN__ flags &= ~(FASYNC + O_NONBLOCK); #else flags &= ~(FASYNC + FNDELAY); #endif flags |= real_mode; #ifndef __CYGWIN__ // not supported by cygnus B20.1 if (mode & FASYNC) { if (fcntl (socknum, F_SETOWN, getpid ()) == -1) { perror("SETOWN failed"); exit(0); } } #endif // ! __CYGWIN__ // if (fcntl (socknum, F_SETFL, flags) == -1) { perror("SETFL failed"); exit(0); } #ifdef __CYGWIN__ if (mode & FASYNC) { if (ioctl (socknum, FIOASYNC, &yes) == -1) { perror("FIOASYNC failed"); exit(0); } } #endif // __CYGWIN__ // } int main(int argc, char *argv[]) { int socknum; char host_buffer[100]; struct hostent * host_entry; struct sockaddr_in * address; struct sigaction action; sigset_t block_mask; int i,n,wait; void * memory; if ( argc < 3 ) { printf("need a hostname and a repeat count\n"); exit(0); } strncpy(host_buffer, argv[1], 100); n = atoi(argv[2]); if ( n < 1 ) { printf("count %d is not ok\n", n); exit(0); } /* allocate socket and connect to server */ socknum = socket(AF_INET, SOCK_STREAM, 0); if ( ! socknum ) { perror("socknum is 0"); exit(0); } host_entry = gethostbyname (host_buffer); if (! host_entry) { perror("could not get host entry"); exit(0); } address = (struct sockaddr_in *) calloc (1, sizeof (struct sockaddr_in)); if (! address ) { perror("could not alloc address"); exit(0); } address -> sin_family = AF_INET; memcpy ((char *) &(address -> sin_addr), (char *) host_entry -> h_addr, host_entry -> h_length); address -> sin_port = htons(23); if (connect (socknum, (struct sockaddr *)address, sizeof (struct sockaddr_in)) == -1) { perror("connect failed"); exit(0); } /* sigaction */ global_int = 0; sigemptyset (&block_mask); sigaddset (&block_mask, SIGINT); sigaddset (&block_mask, SIGQUIT); sigaddset (&block_mask, SIGTSTP); sigaddset (&block_mask, SIGIO); // note that SA_RESTART is not supported on cygnus prior to 1.1.8 action.sa_handler = handle_signal; action.sa_mask = block_mask; action.sa_flags = SA_RESTART; if (sigaction (SIGIO, &action, (struct sigaction *) 0) == -1) { perror("sigaction failed"); exit(0); } /* set async mode */ set_mode (socknum, FNDELAY + FASYNC); for ( i = 0; i < n ; i++ ) { if ( send (socknum, host_buffer, 1, 0) == -1 ) { perror("send failed"); exit(0); } for ( wait = 0; wait < 1000; wait++ ) { memory = malloc(1000); if ( !memory ) { perror("malloc failed"); continue; } free(memory); } } printf("Everything went ok, global_int is %d!\n", global_int); return 0; }
-- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Bug reporting: http://cygwin.com/bugs.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/