⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 atd.cpp

📁 Trolltech公司发布的图形界面操作系统。可在qt-embedded-2.3.10平台上编译为嵌入式图形界面操作系统。
💻 CPP
字号:
/************************************************************************ Copyright (C) 2000-2005 Trolltech AS and its licensors.** All rights reserved.**** This file is part of the Qtopia Environment.**** This file may be distributed and/or modified under the terms of the** GNU General Public License version 2 as published by the Free Software** Foundation and appearing in the file LICENSE.GPL included in the** packaging of this file.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.**** See http://www.trolltech.com/gpl/ for GPL licensing information.** See below for additional copyright and license information**** Contact info@trolltech.com if any conditions of this licensing are** not clear to you.************************************************************************//* *	Lightweight At Daemon * *	Compile with: *		gcc -s -Wall -Wstrict-prototypes atd.c -o atd * *	Copyright (C) 1996, Paul Gortmaker. *	Copyright (C) 2001, Russell Nelson * *	Released under the GNU General Public License, version 2, *	included herein by reference. * */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <linux/rtc.h>/*#include "rtc.h"*/#include <sys/ioctl.h>#include <sys/time.h>#include <sys/select.h>#include <time.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/wait.h>#include <limits.h>#include <fcntl.h>#include <unistd.h>#include <errno.h>#include <dirent.h>#include <syslog.h>#include "atd.h"/*! \class atd atd.h \brief The atd class is a placeholder for licensing information. \legalese The atd program is based on Russ Nelson's lightweight At daemon. It is distributed under the terms of the GNU General Public License. The atd program is based on Russ Nelson's lightweight At daemon. The At daemon will run a program at a specified time. It is distributed under the terms of the GNU General Public License.*/atd::atd(){}#ifdef QT_QWS_SL5XXX#include <asm/sharp_apm.h>#include <asm/hardware.h># define BUGGY_RTC_SELECT#else# define BROKEN_RTC_ALARM#endif#define DAEMONint compare_rtc_to_tm(struct rtc_time *rtc, struct tm *tm){  int i;          i = rtc->tm_year - tm->tm_year;  if (!i) i = rtc->tm_mon - tm->tm_mon;  if (!i) i = rtc->tm_mday - tm->tm_mday;  if (!i) i = rtc->tm_hour - tm->tm_hour;  if (!i) i = rtc->tm_min - tm->tm_min;  if (!i) i = rtc->tm_sec - tm->tm_sec;  if (!i) return 0;  if (i > 0) return 1;  return -1;}void waitfor(time_t t) {  int rtcfd, tfd, retval= 0;  unsigned long data;  struct rtc_time rtc_tm;  time_t now;  struct tm *tm;  struct timeval tv;  int nfds;  fd_set afds;  int setTime = 0; /*We don't have bool in C...*/#ifdef DAEMON  syslog(LOG_DEBUG, "waitfor %ld\n", t);#else  printf("waitfor %ld\n", t);#endif  rtcfd = open ("/dev/rtc", O_RDONLY);  if (rtcfd ==  -1) {#ifdef DAEMON    syslog(LOG_ERR, "/dev/rtc: %m\n");    closelog();#else    perror("/dev/rtc");#endif    exit(errno);  }  tfd = open ("trigger", O_RDWR);  if (tfd ==  -1) {#ifdef DAEMON    syslog(LOG_ERR, "trigger: %m\n");    closelog();#else    perror("trigger");#endif    exit(errno);  }  /* Read the RTC time/date */  retval = ioctl(rtcfd, RTC_RD_TIME, &rtc_tm);  if (retval == -1) {#ifdef DAEMON      syslog(LOG_ERR, "ioctl: %m\n");      closelog();#else      perror("ioctl");#endif      exit(errno);  }#ifdef DAEMON  syslog(LOG_DEBUG, "Current RTC date/time is %d-%d-%d, %02d:%02d:%02d.\n",    rtc_tm.tm_mday, rtc_tm.tm_mon + 1, rtc_tm.tm_year + 1900,    rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec);#else  printf("Current RTC date/time is %d-%d-%d, %02d:%02d:%02d.\n",    rtc_tm.tm_mday, rtc_tm.tm_mon + 1, rtc_tm.tm_year + 1900,    rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec);#endif  tm = gmtime(&t);#ifdef DAEMON  syslog(LOG_DEBUG, "Alarm date/time is %d-%d-%d, %02d:%02d:%02d.\n",    tm->tm_mday, tm->tm_mon + 1, tm->tm_year + 1900,    tm->tm_hour, tm->tm_min, tm->tm_sec);#else  printf("Alarm date/time is %d-%d-%d, %02d:%02d:%02d.\n",    tm->tm_mday, tm->tm_mon + 1, tm->tm_year + 1900,    tm->tm_hour, tm->tm_min, tm->tm_sec);#endif  if (t && compare_rtc_to_tm(&rtc_tm, tm) >= 0) {    close(rtcfd);    close(tfd);    return;  }#ifdef BROKEN_RTC_ALARM  /* Workaround for broken same day only RTC */  /* If the next alarm is not today, set the alarm for midnight */  if (tm->tm_mday != rtc_tm.tm_mday ||      tm->tm_mon != rtc_tm.tm_mon ||      tm->tm_year != rtc_tm.tm_year) {    tm->tm_hour = 23;    tm->tm_min = 59;    tm->tm_sec = 59;    } #endif  if (t) {    /* set the alarm */#ifndef BROKEN_RTC_ALARM    rtc_tm.tm_mday  = tm->tm_mday;     rtc_tm.tm_mon = tm->tm_mon;    rtc_tm.tm_year = tm->tm_year;#endif    rtc_tm.tm_sec = tm->tm_sec;    rtc_tm.tm_min = tm->tm_min;    rtc_tm.tm_hour = tm->tm_hour;    retval = ioctl(rtcfd, RTC_ALM_SET, &rtc_tm);    if (retval == -1) {#ifdef DAEMON      syslog(LOG_ERR, "ioctl: %m\n");      closelog();#else      perror("ioctl");#endif      exit(errno);    }    /* Read the current alarm settings */    retval = ioctl(rtcfd, RTC_ALM_READ, &rtc_tm);    if (retval == -1) {#ifdef DAEMON      syslog(LOG_ERR, "ioctl: %m\n");      closelog();#else      perror("ioctl");#endif      exit(errno);    }#ifdef DAEMON    syslog(LOG_DEBUG, "Alarm time now set to %d-%02d-%02d %02d:%02d:%02d.\n",	   rtc_tm.tm_mday, rtc_tm.tm_mon + 1, rtc_tm.tm_year + 1900,	   rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec);#else    printf("Alarm time now set to %d-%02d-%02d %02d:%02d:%02d.\n",	   rtc_tm.tm_mday, rtc_tm.tm_mon + 1, rtc_tm.tm_year + 1900,	   rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec);#endif    /* Enable alarm interrupts */    retval = ioctl(rtcfd, RTC_AIE_ON, 0);    if (retval == -1) {#ifdef DAEMON      syslog(LOG_ERR, "ioctl: %m\n");      closelog();#else      perror("ioctl");#endif      exit(errno);    }  }#ifdef DAEMON  syslog(LOG_DEBUG, "Waiting for alarm...");#else  printf("Waiting for alarm...");  fflush(stdout);#endif  /* This blocks until the alarm ring causes an interrupt */  FD_ZERO(&afds);#ifndef BUGGY_RTC_SELECT  if (t) FD_SET(rtcfd, &afds);#endif  FD_SET(tfd, &afds);  nfds = rtcfd+1;  if (tfd > rtcfd) nfds = tfd + 1;#ifndef BUGGY_RTC_SELECT  /* Wait up to ten minutes. */  tv.tv_sec = 10*60;#else  /* Only up to 30 seconds, since we can't use the RTC */  tv.tv_sec = 30;#endif  tv.tv_usec = 0;  if (select(nfds, &afds, (fd_set *) 0,  (fd_set *) 0, &tv) < 0) {    if (errno != EINTR)#ifdef DAEMON      {	syslog(LOG_ERR, "select: %m\n");	closelog();      }#else      perror("select");#endif      exit(errno);  }  if (FD_ISSET(rtcfd, &afds)) {    retval = read(rtcfd, &data, sizeof(unsigned long));    if (retval == -1) {#ifdef DAEMON      syslog(LOG_ERR, "read: %m\n");      closelog();#else      perror("read");#endif      exit(errno);    }  }  if (FD_ISSET(tfd, &afds)) {      char buf[8];      int i;      retval = read(tfd, buf, 8);      if (retval == -1) {#ifdef DAEMON	  syslog(LOG_ERR, "read: %m\n");	  closelog();#else	  perror("read");#endif	  exit(errno);      }#ifdef DAEMON      syslog(LOG_DEBUG, "TRIGGER %d ", retval);#else      printf( "TRIGGER %d ", retval );#endif      for ( i = 0; i < retval; i++ )	  if (( setTime = ( buf[i] == 'W' ) ))	      break;  }#ifdef DAEMON  syslog(LOG_DEBUG, " okay. Alarm rang.\n");#else  printf(" okay. Alarm rang.\n");#endif  if ( setTime ) {      /* Set the RTC time/date */#ifdef DAEMON      syslog(LOG_DEBUG, "Setting RTC\n");#else      printf( "Setting RTC\n" );#endif      now = time(NULL);      tm = gmtime(&now);      rtc_tm.tm_mday = tm->tm_mday;      rtc_tm.tm_mon = tm->tm_mon;      rtc_tm.tm_year = tm->tm_year;      rtc_tm.tm_hour = tm->tm_hour;      rtc_tm.tm_min = tm->tm_min;      rtc_tm.tm_sec = tm->tm_sec;      retval = ioctl(rtcfd, RTC_SET_TIME, &rtc_tm);      if (retval == -1) {#ifdef DAEMON	  syslog(LOG_ERR, "ioctl: %m\n");	  closelog();#else	  perror("ioctl");#endif	  exit(errno);      }  }  /* Disable alarm interrupts */  retval = ioctl(rtcfd, RTC_AIE_OFF, 0);  if (retval == -1) {#ifdef DAEMON    syslog(LOG_ERR, "ioctl: %m\n");    closelog();#else    perror("ioctl");#endif    exit(errno);  }  close(rtcfd);  close(tfd);}int runjob(char *fn){  pid_t pid;  int status;  pid = fork();  if (pid == -1)    return -1;  if (pid == 0) {#ifdef DAEMON    syslog(LOG_DEBUG, "running %s\n", fn);#else    printf("running %s\n", fn);#endif    execl(fn, fn, NULL);    exit(127);  }  do {#ifdef DAEMON    syslog(LOG_DEBUG, "waiting for %d\n", pid);#else    printf("waiting for %d\n", pid);#endif    if (waitpid(pid, &status, 0) == -1) {      if (errno != EINTR)        return -1;      }    break;  } while(1);  return 0;}unsigned long nameok(const char *name){  char *middle;  char *end;  unsigned long that;  /* check for timestamp.pid */  that = strtol(name, &middle, 10);  if (*middle != '.')    return 0;  strtol(middle+1, &end, 10);  if (name + strlen(name) != end)    return 0;  return that;}void die(char *s){#ifdef DAEMON  syslog(LOG_ERR, "%s\n", s);  closelog();#else  fprintf(stderr, "%s\n", s);#endif  exit(2);}static void enable_rtc_wakeup(void){#ifdef QT_QWS_SL5XXX  int fd, cur_val, ret;  /* enable RTC wakeup */  fd = open ("/dev/apm_bios", O_WRONLY);  if (fd ==  -1) {#ifdef DAEMON    syslog(LOG_ERR, "/dev/apm_bios: %m\n");    closelog();#else    perror("/dev/apm_bios");#endif    exit(errno);  }  cur_val = ioctl(fd, APM_IOCGWUPSRC, 0);  if (cur_val == -1) {#ifdef DAEMON    syslog(LOG_ERR, "ioctl: %m\n");    closelog();#else    perror("ioctl");#endif    exit(errno);  }  ret = ioctl(fd, APM_IOCSWUPSRC, cur_val | PWER_RTC);  if (ret == -1) {#ifdef DAEMON    syslog(LOG_ERR, "ioctl: %m\n");    closelog();#else    perror("ioctl");#endif    exit(errno);  }  close(fd);#endif}int main(int argc, char *argv[]) {  struct dirent *dirent;  DIR *dir;  unsigned long that, next, now;#ifdef DAEMON  if (argc != 2) {    fprintf(stderr, "usage: atd spooldir\n");    exit(2);  }  {    int	pid;    pid = fork();    if (pid > 0) {      exit(0);    } else if (pid < 0) {      exit(-1);    }  }  if (setsid() == -1) {    exit(-1);  }  close(0);  close(1);  close(2);  openlog("atd", LOG_PID, LOG_DAEMON);#else  if (argc != 2) die("usage: atd spooldir");#endif  if (chdir(argv[1]) < 0) die("cannot chdir");  if (mkfifo("trigger.new", 0777) < 0) die("cannot mkfifo trigger.new");  if (rename("trigger.new","trigger")) die("cannot rename trigger.new");  enable_rtc_wakeup();  while(1) {    /* run all the jobs in the past */    now = time(NULL);    dir = opendir(".");    while ((dirent = readdir(dir))) {      that = nameok(dirent->d_name);      /* run jobs which are in the past, and find the next job in the future */      /* avoid race conditions. Run jobs scheduled for the next second now */      if (that)        if (that <= now + 1) runjob(dirent->d_name);    }    closedir(dir);    /* find the next job in the future.  A job we just ran might have     * rescheduled itself.  */    dir = opendir(".");    next = ULONG_MAX;    while ((dirent = readdir(dir))) {      that = nameok(dirent->d_name);      /* schedule jobs that we haven't just run */      if (that)         if (that > now + 1)          if (that < next) next = that;    }    closedir(dir);#ifdef DAEMON    syslog(LOG_DEBUG, "next: %ld\n", next);#else    printf("next: %ld\n", next);#endif    if (next == ULONG_MAX) next = 0;    waitfor(next);  }#ifdef DAEMON  closelog();#endif  return 0;} 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -