This is the mail archive of the cygwin@cygwin.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

connect() not interrupted by sigalrm?


Cygwin version:		1.3.20-1
Win OS tested:		NT 4.0/SP6 and XP

I have an application that calls alarm() before connect() in order to
prevent connect() from hanging if the host is down or non-existent.
When alarm() goes off, it sends the SIGALRM signal, which interrupts
the connect() system call.  This works under Linux, Solaris, OSF, and
Mac OS X, but apparently not under Cygwin. As shown in the appended
code, the alarm does go off and can trigger an associated alarm
function, but the connect() system call is not interrupted.

This problem appears to be similar to a previous report:

    * From: Corinna Vinschen <cygwin at cygwin dot com>
    * To: cygwin <cygwin at cygwin dot com>
    * Date: Fri, 22 Feb 2002 22:11:25 +0100
    * Subject: Re: recvfrom and timeout signal
    * References: <20020221162023 dot N23094 at cygbert dot vinschen dot de> <NDBBKJAFMIEEFNJOJPKLOEIEFCAA dot pstepien at aspco dot com dot pl>

concerning the recvfrom() call, in which it was determined that:

   Thanks.  It seems as if CancelIo() doesn't work with WSARecv()
   on 98/Me.  I've search for info in MSDN and I've asked in
   newsgroups but to no avail so far...

Is the answer the same for connect()?

Regards,

Eric Mandel

/*
 * solaris: gcc -o atest atest.c -lsocket -lnsl
 * linux: gcc -o atest atest.c
 * os x: gcc -o atest atest.c
 */
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>

/* the domain exists but not the machine */
#define BOGUSIP "131.142.47.110"

static int alarm_flag=0;
static struct sigaction act1, oact1;

static void AlarmFunc (int signo)
{
  alarm_flag = 1;
}

int main(int argc, char **argv)
{
  int status;
  int fd;
  int timeout=2;
  unsigned int ip;
  struct sockaddr_in sock_in;

  /* arg 1: timeout */
  if( argc > 1 )
    timeout = atoi(argv[1]);

  /* set up socket to a bogus ip and port */
  if( (int)(ip = inet_addr(BOGUSIP)) == -1 ){
    perror("inet_addr");
    exit(1);
  }
  if( (fd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ){
    perror("socket");
    exit(1);
  }
  memset((char *)&sock_in, 0, sizeof(sock_in));
  sock_in.sin_family = AF_INET;
  sock_in.sin_addr.s_addr = ip;
  sock_in.sin_port = htons(14285);

  /* set up alarm */
  act1.sa_handler = AlarmFunc;
  sigemptyset(&act1.sa_mask);
  act1.sa_flags = 0;
#ifdef SA_INTERRUPT
  act1.sa_flags |= SA_INTERRUPT;
#endif
  if( sigaction(SIGALRM, &act1, &oact1) < 0 ){
    perror("sigaction");
    exit(1);
  }

  /* start alarm */
  alarm(timeout);
  /* try to connect -- usually hangs */
  status=connect(fd, (struct sockaddr *)&sock_in, sizeof(sock_in));
  /* turn off alarm if it did not go off */
  alarm(0);

  /* if alarm_flag is 1, alarm went off and interrupted connect */
  fprintf(stderr, "alarm did%sgo off\n", alarm_flag?" ":" NOT ");
  fprintf(stderr, "alarm_flag=%d status=%d\n", alarm_flag, status);
  if( status != 0 ){
    perror("connect");
  }
}

--
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/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]