Jump to content

Welcome to Geeks to Go - Register now for FREE

Need help with your computer or device? Want to learn new tech skills? You're in the right place!
Geeks to Go is a friendly community of tech experts who can solve any problem you have. Just create a free account and post your question. Our volunteers will reply quickly and guide you through the steps. Don't let tech troubles stop you. Join Geeks to Go now and get the support you need!

How it Works Create Account
Photo

sigaction in C displaying 2 messages


  • Please log in to reply

#1
bvjens31

bvjens31

    Member

  • Member
  • PipPip
  • 25 posts
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.

#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);
}


snapshot1.jpg


Thanks in advance!
Chris
  • 0

Advertisements


#2
Ax238

Ax238

    Tech Staff

  • Technician
  • 1,323 posts
A couple things I see here that may or may not be problematic:
  • int main(int argc, char ** argv) {
      ...
      memset (&sa3,0,sizeof(sa2));
      ...
    Maybe it doesn't matter, but should this last line be the following?
    memset (&sa3,0,sizeof(sa3));
  • 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:

...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
  • 0






Similar Topics

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

As Featured On:

Microsoft Yahoo BBC MSN PC Magazine Washington Post HP