linux crond定时任务源码分析
来源:互联网 发布:中国高速铁路 知乎 编辑:程序博客网 时间:2024/06/08 14:33
关于crond的介绍和使用,请百度。这里分析下如何实现。 下载源码:http://down1.chinaunix.net/distfiles/vixie-cron-4.1.tar.bz2 该源码中主要由以下两个主要的.c组成: 1:cron.c 2:crontab.c 首先看下crontab.c,这个文件主要实现了crontab命令,来管理配置文件。 main函数:
intmain(int argc, char *argv[]) { int exitstatus; Pid = getpid(); ProgramName = argv[0]; setlocale(LC_ALL, "");#if defined(BSD) setlinebuf(stderr);#endif parse_args(argc, argv); /* sets many globals, opens a file */ set_cron_cwd(); if (!allowed(RealUser, CRON_ALLOW, CRON_DENY)) { fprintf(stderr, "You (%s) are not allowed to use this program (%s)\n", User, ProgramName); fprintf(stderr, "See crontab(1) for more information\n"); log_it(RealUser, Pid, "AUTH", "crontab command not allowed"); exit(ERROR_EXIT); } exitstatus = OK_EXIT; switch (Option) { case opt_unknown: exitstatus = ERROR_EXIT; break; case opt_list: list_cmd(); break; case opt_delete: delete_cmd(); break; case opt_edit: edit_cmd(); break; case opt_replace: if (replace_cmd() < 0) exitstatus = ERROR_EXIT; break; default: abort(); } exit(exitstatus); /*NOTREACHED*/}
1. 解析函数入参,并设置option变量。2. 根据解析出的option变量,分别调用对应的函数。涉及到的函数实现为列出配置、删除配置、指定配置文件、编辑配置文件。列出配置和删除配置相对简单,分别是读取文件和删除文件。不做分析,接下来主要看下如何编辑配置文件和指定配置文件。编辑文件:
static voidedit_cmd(void) { char n[MAX_FNAME], q[MAX_TEMPSTR], *editor; FILE *f; int ch, t, x; struct stat statbuf; struct utimbuf utimebuf; WAIT_T waiter; PID_T pid, xpid; log_it(RealUser, Pid, "BEGIN EDIT", User); if (!glue_strings(n, sizeof n, SPOOL_DIR, User, '/')) { fprintf(stderr, "path too long\n"); exit(ERROR_EXIT); } if (!(f = fopen(n, "r"))) { if (errno != ENOENT) { perror(n); exit(ERROR_EXIT); } fprintf(stderr, "no crontab for %s - using an empty one\n", User); if (!(f = fopen(_PATH_DEVNULL, "r"))) { perror(_PATH_DEVNULL); exit(ERROR_EXIT); } } if (fstat(fileno(f), &statbuf) < 0) { perror("fstat"); goto fatal; } utimebuf.actime = statbuf.st_atime; utimebuf.modtime = statbuf.st_mtime; /* Turn off signals. */ (void)signal(SIGHUP, SIG_IGN); (void)signal(SIGINT, SIG_IGN); (void)signal(SIGQUIT, SIG_IGN); if (!glue_strings(Filename, sizeof Filename, _PATH_TMP, "crontab.XXXXXXXXXX", '/')) { fprintf(stderr, "path too long\n"); goto fatal; } if (-1 == (t = mkstemp(Filename))) { perror(Filename); goto fatal; }#ifdef HAS_FCHOWN if (fchown(t, MY_UID(pw), MY_GID(pw)) < 0) { perror("fchown"); goto fatal; }#else if (chown(Filename, MY_UID(pw), MY_GID(pw)) < 0) { perror("chown"); goto fatal; }#endif if (!(NewCrontab = fdopen(t, "r+"))) { perror("fdopen"); goto fatal; } Set_LineNum(1) /* ignore the top few comments since we probably put them there. */ x = 0; while (EOF != (ch = get_char(f))) { if ('#' != ch) { putc(ch, NewCrontab); break; } while (EOF != (ch = get_char(f))) if (ch == '\n') break; if (++x >= NHEADER_LINES) break; } /* copy the rest of the crontab (if any) to the temp file. */ if (EOF != ch) while (EOF != (ch = get_char(f))) putc(ch, NewCrontab); fclose(f); if (fflush(NewCrontab) < OK) { perror(Filename); exit(ERROR_EXIT); } utime(Filename, &utimebuf); again: rewind(NewCrontab); if (ferror(NewCrontab)) { fprintf(stderr, "%s: error while writing new crontab to %s\n", ProgramName, Filename); fatal: unlink(Filename); exit(ERROR_EXIT); } if (((editor = getenv("VISUAL")) == NULL || *editor == '\0') && ((editor = getenv("EDITOR")) == NULL || *editor == '\0')) { editor = EDITOR; } /* we still have the file open. editors will generally rewrite the * original file rather than renaming/unlinking it and starting a * new one; even backup files are supposed to be made by copying * rather than by renaming. if some editor does not support this, * then don't use it. the security problems are more severe if we * close and reopen the file around the edit. */ switch (pid = fork()) { case -1: perror("fork"); goto fatal; case 0: /* child */ if (setgid(MY_GID(pw)) < 0) { perror("setgid(getgid())"); exit(ERROR_EXIT); } if (setuid(MY_UID(pw)) < 0) { perror("setuid(getuid())"); exit(ERROR_EXIT); } if (chdir(_PATH_TMP) < 0) { perror(_PATH_TMP); exit(ERROR_EXIT); } if (!glue_strings(q, sizeof q, editor, Filename, ' ')) { fprintf(stderr, "%s: editor command line too long\n", ProgramName); exit(ERROR_EXIT); } execlp(_PATH_BSHELL, _PATH_BSHELL, "-c", q, (char *)0); perror(editor); exit(ERROR_EXIT); /*NOTREACHED*/ default: /* parent */ break; } /* parent */ for (;;) { xpid = waitpid(pid, &waiter, WUNTRACED); if (xpid == -1) { if (errno != EINTR) fprintf(stderr, "%s: waitpid() failed waiting for PID %ld from \"%s\": %s\n", ProgramName, (long)pid, editor, strerror(errno)); } else if (xpid != pid) { fprintf(stderr, "%s: wrong PID (%ld != %ld) from \"%s\"\n", ProgramName, (long)xpid, (long)pid, editor); goto fatal; } else if (WIFSTOPPED(waiter)) { kill(getpid(), WSTOPSIG(waiter)); } else if (WIFEXITED(waiter) && WEXITSTATUS(waiter)) { fprintf(stderr, "%s: \"%s\" exited with status %d\n", ProgramName, editor, WEXITSTATUS(waiter)); goto fatal; } else if (WIFSIGNALED(waiter)) { fprintf(stderr, "%s: \"%s\" killed; signal %d (%score dumped)\n", ProgramName, editor, WTERMSIG(waiter), WCOREDUMP(waiter) ?"" :"no "); goto fatal; } else break; } (void)signal(SIGHUP, SIG_DFL); (void)signal(SIGINT, SIG_DFL); (void)signal(SIGQUIT, SIG_DFL); if (fstat(t, &statbuf) < 0) { perror("fstat"); goto fatal; } if (utimebuf.modtime == statbuf.st_mtime) { fprintf(stderr, "%s: no changes made to crontab\n", ProgramName); goto remove; } fprintf(stderr, "%s: installing new crontab\n", ProgramName); switch (replace_cmd()) { case 0: break; case -1: for (;;) { printf("Do you want to retry the same edit? "); fflush(stdout); q[0] = '\0'; (void) fgets(q, sizeof q, stdin); switch (q[0]) { case 'y': case 'Y': goto again; case 'n': case 'N': goto abandon; default: fprintf(stderr, "Enter Y or N\n"); } } /*NOTREACHED*/ case -2: abandon: fprintf(stderr, "%s: edits left in %s\n", ProgramName, Filename); goto done; default: fprintf(stderr, "%s: panic: bad switch() in replace_cmd()\n", ProgramName); goto fatal; } remove: unlink(Filename); done: log_it(RealUser, Pid, "END EDIT", User);}
阅读全文
0 0
- linux crond定时任务源码分析
- linux 定时任务 crond
- linux crond 定时任务
- Linux -- Crond 定时任务
- [Linux] Crond 定时任务
- linux crond 定时任务
- Linux定时任务-crond
- 【Linux】Linux定时任务crond
- LINUX CENTOS 定时任务 crond
- linux定时任务(crond)
- linux下定时执行计划crond任务
- Linux定时任务 - atd和crond
- linux下定时执行计划crond任务
- linux定时任务crond那些事! 【转】
- linux的定时任务crond与crontab
- Linux系统定时任务(crond)
- linux crond定时任务不执行原因
- Linux定时任务之crond/crontab
- opencl笔记
- LeetCode Blog for course "Algorithms" -- Problem 7
- Druid是什么和用StatViewServlet用于展示Druid的统计信息
- Jzoj4714 公约数
- Hdu4859-【】-【拓扑排序+优先队列+逆向处理】
- linux crond定时任务源码分析
- c语言面试题 指针30个常错题型
- CvMat,Mat和IplImage之间的转化和拷贝
- t.test()
- HDU——hdu2389 Rain on your Parade
- C#/.net微信小程序encryptedData解密
- Jsp入门学习1
- 一篇文章搞懂人脸识别的十个概念
- 数值方法