Пример #1
0
void* scan_thread(void *arg)
{
    alsa_rawmidi_t *midi = arg;
    struct pollfd wakeup;

    wakeup.fd = midi->scan.wake_pipe[0];
    wakeup.events = POLLIN|POLLERR|POLLNVAL;
    while (midi->keep_walking) {
        int res;
        //error_log("scanning....");
        scan_cycle(midi);
        res = poll(&wakeup, 1, 2000);
        if (res>0) {
            char c;
            read(wakeup.fd, &c, 1);
        } else if (res<0 && errno != EINTR)
            break;
    }
    return NULL;
}
Пример #2
0
int main(int argc, char **argv)
{
   char spid[16];
   pid_t pid;
   int c;
   size_t lenc, lenl, lenp;
   unsigned int nc_counter, i;
   FILE *pidout;
   struct rlimit rlim;

   nc_counter = 0;

   while (1)
   {
      c = getopt(argc, argv, "dc:");

      if (c == -1)
         break;

      switch (c)
      {
         case 'c':
            CONFNAME = strdup(optarg);
            break;
         case 'd':
            OPT_DEBUG++;
            break;
         case '?':
         default:
            /* Unknown arg, guess we'll just do nothing for now. */
            break;
      }
   }

   lenc = strlen(CONFDIR) + strlen(CONFNAME) + strlen(CONFEXT) + 3;
   lenl = strlen(LOGDIR) + strlen(CONFNAME) + strlen(LOGEXT) + 3;
   lenp = strlen(LOGDIR) + strlen(CONFNAME) + strlen(PIDEXT) + 3;

   CONFFILE = MyMalloc(lenc * sizeof *CONFFILE);
   LOGFILE = MyMalloc(lenl * sizeof *LOGFILE);

   snprintf(CONFFILE, lenc, "%s/%s.%s", CONFDIR, CONFNAME, CONFEXT);
   snprintf(LOGFILE, lenl, "%s/%s.%s", LOGDIR, CONFNAME, LOGEXT);

   /* Fork off. */

   if (OPT_DEBUG <= 0)
   {
      if ((pid = fork()) < 0)
      {
         perror("fork()");
         exit(EXIT_FAILURE);
      }
      else if (pid != 0)
      {
         _exit(EXIT_SUCCESS);
      }

      /* Get us in our own process group. */
      if (setpgid(0, 0) < 0)
      {
         perror("setpgid()");
         exit(EXIT_FAILURE);
      }

      /* Reset file mode. */
      /* shasta: o+w is BAD, mmkay? */
      umask(002);

      /* Close file descriptors. */
      close(STDIN_FILENO);
      close(STDOUT_FILENO);
      close(STDERR_FILENO);

      log_open(LOGFILE);
   }
   else
      log_printf("MAIN -> Debug level %d", OPT_DEBUG);


   log_printf("MAIN -> BOPM %s started.", VERSION);
   log_printf("MAIN -> Reading configuration file...");

   config_load(CONFFILE);

   if (OptionsItem->scanlog)
      scanlog_open(OptionsItem->scanlog);

   pid = getpid();

   pidout = fopen(OptionsItem->pidfile, "w");
   snprintf(spid, 16, "%u", pid);

   if (pidout)
   {
      fwrite(spid, sizeof(char), strlen(spid), pidout);
      fclose(pidout);
   }
   else
   {
      log_printf("MAIN -> Error opening %s: %s", OptionsItem->pidfile,
          strerror(errno));
      exit(EXIT_FAILURE);
   }

   /* Setup alarm & int handlers. */

   ALARMACTION.sa_handler = &(do_signal);
   ALARMACTION.sa_flags = SA_RESTART;
   INTACTION.sa_handler = &(do_signal);
   USR1ACTION.sa_handler = &(do_signal);

   sigaction(SIGALRM, &ALARMACTION, 0);
   sigaction(SIGINT, &INTACTION, 0);
   sigaction(SIGUSR1, &USR1ACTION, 0);

   /* Ignore SIGPIPE. */
   signal(SIGPIPE, SIG_IGN);

   alarm(1);

   while (1)
   {
      

      /* Main cycles */
      irc_cycle();
      scan_cycle();


      /* Restart bopm if main_restart() was called (usually happens by m_kill in irc.c) */
      if(RESTART)
      {
         /* If restarted in debug mode, die */
         if(OPT_DEBUG)
            return(1); 

         log_printf("MAIN -> Restarting process");

         /* Get upper file descriptor limit */
         if(getrlimit(RLIMIT_NOFILE, &rlim) == -1) 
         {
            log_printf("MAIN RESTART -> getrlimit() error retrieving RLIMIT_NOFILE (%s)", strerror(errno));
            return(1); 
         }

         /* Set file descriptors 0-rlim_cur close on exec */
         for(i = 0; i < rlim.rlim_cur; i++)
            fcntl(i, F_SETFD, FD_CLOEXEC);

         /* execute new process */
         if(execve(argv[0], argv, NULL) == -1)
            log_printf("MAIN RESTART -> Execution of \"%s\" failed. ERROR: %s", argv[0], strerror(errno));

         /* Should only get here if execve failed */
         RESTART = 0;
      }

      /* Check for log reopen */
      if(REOPEN)
      {
         log_printf("MAIN -> Caught SIGUSR1, reopening logfiles");
         log_close();
         log_open(LOGFILE);

         if(OptionsItem->scanlog)
         {
            scanlog_close();
            scanlog_open(OptionsItem->scanlog);
         }

         log_printf("MAIN -> reopened logfiles");

         REOPEN = 0;
      }

      /* Call 1 second timers */
      if(ALARMED)
      {
         irc_timer();
         scan_timer();
         command_timer();

         ALARMED = 0;
      }


   }

   if (!OPT_DEBUG)
      log_close();

   /* If there's no scanlog open then this will do nothing anyway */
   scanlog_close();

   return(0);
}