Linux boot and release issues

I have a problem with the below code that calls getutent () to count the total number of users that are currently logged in. The timer will be called every 1 second and will set the boolean name "isSigAlrmOccured" to true and exit. The main function checks if the timer signal has been delivered by checking this parameter and keeping track of the number of users loggedin. Unfortunately, the timer signal is delivered to the main program only twice correctly, and after that I don't receive any additional signals. The pause function call is not interrupted after the first two signals.

#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <utmp.h>
#include <errno.h>

static int isSigAlrmOccured;

void alarm_handler (int signo)
{
  static int i=1;
  printf("\n Signal Occurred %d times\n",i++);
  isSigAlrmOccured = 1;

}

int main (int argc, char *argv[]) {
   struct itimerval delay;
   struct utmp *utmpstruct;
   int numuser;


   int ret;
   signal (SIGALRM, alarm_handler);
   delay.it_value.tv_sec = 1;
   delay.it_value.tv_usec = 0;
   delay.it_interval.tv_sec = 1;
   delay.it_interval.tv_usec = 0;
   ret = setitimer (ITIMER_REAL, &delay, NULL);
   if (ret) {
     perror ("setitimer");
     return 0;
   }
   for (;;) {
       pause ( );
       /* count the number of users */
       if ( (errno == EINTR) && (isSigAlrmOccured) ) {
           isSigAlrmOccured = 0;
           setutent();
           while ((utmpstruct = getutent())) {
           if ((utmpstruct->ut_type == USER_PROCESS) &&
               (utmpstruct->ut_name[0] != '\0'))
               numuser++;
           }
           endutent();
       }
   }
   return 0;
}

      

Output:

Signal occurred 1 time

Signal occurred 2 times

+2


source to share


2 answers


The * utent () implementation uses alarm () and overwrites your alarm.
You will need to do something else.

strace ttest (some lines removed for brevity)
[...]
pause ()
--- SIGALRM (alarm) @ 0 (0) ---
write (1, "Signal occurred 1 time \ n", 25 Signal occurred 1 time ) = 25
open ("/ var / run / utmp", O_RDONLY | O_CLOEXEC) = 3
alarm clock (0) = 5
rt_sigaction (SIGALRM, {0x7f52580a91c0, [], SA_RESTORER, 0x7f5257fd46e0}, {0x40075c, [ALREST SA_RESTART, 0x7f5257fd46e0}, 8) = 0
alarm (1) = 0



Sample code that only sets an alarm during a waiting period.

#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <utmp.h>
#include <errno.h>

static int isSigAlrmOccured;

void alarm_handler (int signo)
{
  static int i=1;
  printf("\n Signal Occurred %d times\n",i++);
  isSigAlrmOccured = 1;

}

int main (int argc, char *argv[]) {
   struct itimerval delay;
   struct utmp *utmpstruct;
   int numuser;
   int ret;

   for (;;) {
   signal (SIGALRM, alarm_handler);
       alarm(1);       /* wake me later */
       pause ( );
       /* count the number of users */
       if ( (errno == EINTR) && (isSigAlrmOccured) ) {
       signal (SIGALRM, SIG_DFL);
           isSigAlrmOccured = 0;
           numuser = 0;
           setutent();
           while ((utmpstruct = getutent())) {
           if ((utmpstruct->ut_type == USER_PROCESS) &&
               (utmpstruct->ut_name[0] != '\0'))
               numuser++;
           }
           endutent();
           printf("found %d users\n", numuser);
       }
   }
   return 0;
}

      

+7


source


This page contains a list of functions that are "safe" to be called from a signal handler. If you call some other function, the behavior is undefined. I notice that setutent()

doesn't seem to actually be, for starters ...



+1


source







All Articles