Link to home
Start Free TrialLog in
Avatar of bcarder
bcarder

asked on

sendto & signals

I'm writing a procedure that creates a UDP socket with a piece of hardware. In my code I basically do this:
     create the socket()
     bind() the socket
     sendto () try to setup comm.
     recvfrom () receive response

but if this hw is not turned on, then my code just waits indefinity for a response.

I'm trying to us the setitimer to time the sendto out, but its not working.  I setup the setitimer and trap the signal but the code never sends a signal.

  signal (SIGALRM, function_call);
  setitimer (ITIMER_REAL, &itv, (struct itimerval *) 0);

I'm missing something, between sendto & setitimer?  Any ideas?
ASKER CERTIFIED SOLUTION
Avatar of ufolk123
ufolk123

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of bcarder
bcarder

ASKER

yes I had some printf statements in the sig handler.  That function consist of three printf statements followed by a call to another function to terminate the process.

As far as the race condition, I up the timer time to 10 seconds and it still just waits.

I will check into the sigaction.

What other information would you like?
Could you post me sample of your code ?


Regards,
ufolk123
Avatar of bcarder

ASKER

Here is the code where I'm trying to connect and trapping the signal.  Good Luck!

#include <unistd.h>
int InitAtlasInterface(SERVER_REC *server_info)
{
   extern void Terminate_Control_Spacecraft();

   struct itimerval value, value2;
   struct sockaddr_in maestro_addr;
   ATLAS_INTERFACE msg;
   int portNumber,len;
   static struct hostent *host = NULL;
   size_t atlas_size, msg_size, maestro_size;
   int error;
   char host_name[64];

   /* Setup to send inital message to atlas 360 */
   memset(&msg, 0, sizeof(msg));
   bzero(&msg,sizeof(msg));
   msg.type = WPWR_MESS;
   msg.cmd = ATLAS_BKEN_OPEN;
   bzero(msg.tgtName,sizeof(msg.tgtName));
   msg.data[0]=2;
   msg_size = sizeof(msg);


   /* Retreive info for machine Maestro is run from */
   gethostname (host_name, 64);
   host = gethostbyname (host_name);

   if (!host)
   {
      return FAIL;
   }

   /* Setup to bind the socket */
   memset((char *) &maestro_addr, 0, sizeof(struct sockaddr_in));
   bzero((char *)&maestro_addr,sizeof(maestro_addr));
   maestro_addr.sin_family = AF_INET;
   bcopy ((char *) host->h_addr, (char *) &maestro_addr.sin_addr,
         host->h_length);
   maestro_addr.sin_port = 0;
   maestro_size = sizeof(atlas_addr);
   len = sizeof(struct sockaddr_in);

   /* Retreive info for Atlas interface is run from */
   host = gethostbyname (server_info->machine_name);
   portNumber = Get_Port_By_Service(server_info->server_name);

   if (!host)
   {
      return FAIL;
   }
   else if (portNumber <= 0)
   {
      return FAIL;
   }

   /* Setup to sendto the Atlas */
   memset((char *) &atlas_addr, 0, sizeof(struct sockaddr_in));
   bzero((char *)&atlas_addr,sizeof(atlas_addr));
   atlas_addr.sin_family = AF_INET;
   bcopy ((char *) host->h_addr, (char *) &atlas_addr.sin_addr,
             host->h_length);
   atlas_addr.sin_port = portNumber;
   atlas_size = sizeof(atlas_addr);

   if ((server_info->server_handle  =  socket(AF_INET,SOCK_DGRAM,0) ) < 0)
   {
      fprintf(stderr, "InitAtlasInterface - can not open sock on %s\n",
                                  server_info->machine_name);
      server_info->server_handle = 0;
      server_info->server_instance = 0;
      return FAIL;
   }

   if (bind(server_info->server_handle,(struct sockaddr *)&maestro_addr,
                maestro_size) < 0)
   {
      fprintf(stderr, "InitAtlasInterface - can not bind %s\n",
                        server_info->machine_name);
      server_info->server_handle = 0;
      server_info->server_instance = 0;
      return FAIL;
   }

   Trap_Signals ();

   value.it_interval.tv_sec  = 0;
   value.it_interval.tv_usec = 0;
   value.it_value.tv_usec   = 0;
   value.it_value.tv_sec    = 10;

   error = setitimer (ITIMER_REAL, &value, (struct itimerval *) 0);
 
   if (sendto (server_info->server_handle,(void *)&msg,msg_size,0,
               (struct sockaddr *)&atlas_addr, atlas_size) < 0)
   {
      fprintf(stderr, "InitAtlasInterface - can not send to %s\n",
                        server_info->server_name);
      server_info->server_handle = 0;
      server_info->server_instance = 0;
      return FAIL;
   }
   else
   {
      value.it_interval.tv_sec  = 0;
      value.it_interval.tv_usec = 0;
      value.it_value.tv_sec  = 0;
      value.it_value.tv_usec = 0;

      setitimer (ITIMER_REAL, &value, (struct itimerval *) 0);
   }

   if (recvfrom(server_info->server_handle,(void *)&msg, msg_size,0,
                (struct sockaddr *)&atlas_addr, &len) < 0)
   {
      fprintf(stderr, "InitAtlasInterface - did not receive message from %s\n",
                        server_info->server_name);
      server_info->server_handle = 0;
      server_info->server_instance = 0;
      return FAIL;
   }

   fprintf(stderr, "InitAtlasInterface: port # %d\n", atlas_addr.sin_port);
   fprintf(stderr, "InitAtlasInterface: ACK = %d\n", msg.cmd);
   if (msg.cmd == ATLAS_BKEN_TGTNF)
   {
      fprintf(stderr, "InitAtlasInterface - did not receive CMD ACK from %s\n",
                        server_info->server_name);
      server_info->server_handle = 0;
      server_info->server_instance = 0;
      return FAIL;
   }

   /*server_info->server_instance = ?;*/
   return PASS;
}

static void Trap_Signals ()
{
   extern void Bad_Connect (int);

   signal (SIGALRM, Bad_Connect);
}

void Bad_Connect (int sig_num)
{
   extern void Terminate_Control_Spacecraft();

   fprintf(stderr, "atlas card didn't connect, received interrupt\n");
   fprintf(stderr, "Terminating Commander, must do session init, after\n");
   fprintf(stderr, "Check out atlas card, make sure its POWERED UP!\n");
   Terminate_Control_Spacecraft();
}