Welcome Guest ( Log In | Register )

      
Discover the best free computer help!
Learn more about Geeks to Go by taking the tour. Spyware, virus, trojan, fake security or privacy alerts? Read the malware cleaning guide.
 
Reply to this topicStart new topic
sigaction in C displaying 2 messages
bvjens31
post Apr 21 2008, 10:33 PM
Post #1


Member
**
Posts: 24
OS: XP Pro



Hey I'm using signals in C, one signal increments a counter and the 2nd one resets counter and prints the count to the screen. But when I do a "killall -sigusr2 signalcode", it prints the count out twice. Somehow the first signal handler is passing on the message, but I need the handler to consume it instead, so only one 'count' prints out. Here is my program. Below it is a screenie of what happens when I issue the signals from the left terminal while the program is running in the right terminal. I increment count 5 times by signalling the first handler 5 times, then when I do the signal to the 2nd handler (just once), it prings out twice in the terminal running the program.

CODE
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>

sig_atomic_t count = 0;

void handler (int signal_number) {
  count++;
}

void handler2 (int signal_number) {
  if(count >= 10) {
    printf("You have counted too many digits.\n"
           "You wanted %d and you can only use 9.\n"
           "I can't just grow an extra finger or toe people. Start over.\n",count);
    count = 0;
    }
  else {
      printf("%d\n",count);
    count = 0;
    }
}

void handler3 (int signal_number) {
  printf("Liar! It is not dead (just wounded).\n") ;
}


int main(int argc, char ** argv) {
  struct sigaction sa1, sa2, sa3;
  int pid;
  memset (&sa1, 0, sizeof (sa1));
  sa1.sa_handler = &handler;
  sigaction(SIGUSR1,&sa1,NULL);

  memset (&sa2,0,sizeof(sa2));
  sa2.sa_handler = &handler2;
  sigaction(SIGUSR2,&sa2,NULL);

  memset (&sa3,0,sizeof(sa2));
  sa3.sa_handler = &handler3;
  sigaction(SIGCHLD,&sa3,NULL);

  pid = fork();
  if (pid != 0) {
    for(;;) {
      sleep(1000);
      //printf("I'm awake, where's the coffee\n");
    }
  }
  else {
    for(;;);
  }
  wait(pid);
}



Attached Image



Thanks in advance!
Chris
Go to the top of the page
 
+Quote Post
Ax238
post Apr 23 2008, 01:25 PM
Post #2


TA Moderator
Group Icon
Posts: 1,275
From: SET HOMEPATH
OS: Windows 95/98/2000/XP/Vista



A couple things I see here that may or may not be problematic:
  1. CODE
    int main(int argc, char ** argv) {
      ...
      memset (&sa3,0,sizeof(sa2));
      ...
    Maybe it doesn't matter, but should this last line be the following?
    CODE
    memset (&sa3,0,sizeof(sa3));

  2. CODE
      pid = fork();
    This will create multiple processes with identical but separate address spaces that both execute the code directly after the fork() call. I'm guessing that you get two output values because both parent and child processes are incrementing their own version of count, as well as printing and resetting their own version of count. You could print out count after incrementing it in the first handler to confirm/reject this.


I've not had much experience with C, much less signals in C, but I hope this information gives you some assistance.

There is another thing I found that may be relevant, since I see you are suspending the parent process:
QUOTE (http://www.delorie.com/gnu/docs/glibc/libc_445.html)
...sleep can return sooner if a signal arrives; if you want to wait for a given interval regardless of signals, use select (see section 13.8 Waiting for Input or Output) and don't specify any descriptors to wait for.

This may be the underlying issue, but you may have to debug to figure out either way.

Regards,

Ax
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 User(s) are reading this topic (1 Guests and 0 Anonymous Users)
0 Members:

 


RSS Time is now: 22nd November 2008 - 03:23 PM
Advertisements do not imply our endorsement of that product or service. The forum is run by volunteers who donate their time and expertise. We make every attempt to ensure that the help and advice posted is accurate and will not cause harm to your computer. However, we do not guarantee that they are accurate and they are to be used at your own risk.