Notify 模块作用是执行系统外部脚本,其中 notify_exec函数用在脚本 notify_down 、notify_up、notify_fault 指令
Notify.h 源码
Notify.c的头文件
#ifndef _NOTIFY_H
#define _NOTIFY_H
/* system includes */
extern int system_call(char *cmdline);
extern void closeall(int fd);
extern int notify_exec(char *cmd);
#endif
Notify.c 源码
#include <unistd.h>
#include <stdlib.h>
#include <syslog.h>
#include <fcntl.h>
#include <errno.h>
#include "notify.h"
#include "signals.h"
#include "logger.h"
/* perform a system call */
int
system_call(char *cmdline) // 执行系统的调用
{
int retval;
retval = system(cmdline);
if (retval == 127) {
/* couldn't exec command */
log_message(LOG_ALERT, "Couldn't exec command: %s", cmdline);
} else if (retval == -1) {
/* other error */
log_message(LOG_ALERT, "Error exec-ing command: %s", cmdline);
}
return retval;
}
/* Close all FDs >= a specified value */ //关闭所有打开的文件
void
closeall(int fd)
{
int fdlimit = sysconf(_SC_OPEN_MAX); // Linux 允许同时打开的最大文件数量
while (fd < fdlimit)
close(fd++);
}
/* Execute external script/program */ //执行外部脚本 或者程序
int
notify_exec(char *cmd)
{
pid_t pid;
int ret;
pid = fork();
/* In case of fork is error. */
if (pid < 0) {
log_message(LOG_INFO, "Failed fork process");
return -1;
}
/* In case of this is parent process */
if (pid)
return 0;
signal_handler_destroy();
closeall(0);
open("/dev/null", O_RDWR);
ret = dup(0); //dup应该是调用fork创建子进程,在写时复制的时候子进程拥有父进程同样的上下文时候用来克隆
if (ret < 0) {
log_message(LOG_INFO, "dup(0) error");
}
ret = dup(0);
if (ret < 0) {
log_message(LOG_INFO, "dup(0) error");
}
system_call(cmd);
exit(0);
}
#############################################################################################################################
其他问题解释:
dup 和 dup2 都可以用来复制一个现存的文件描述符。经常用来重新定向进程的 STDIN, STDOUT, STDERR。
dup 函数
dup 函数定义在 <unistd.h> 中,函数原形为:
int dup ( int filedes ) ;
函数返回一个新的描述符,这个新的描述符是传给它的描述符的拷贝,若出错则返回 -1。由dup返回的新文件描述符一定是当前可用文件描述符中的最小数值。这函数返回的新文件描述符与参数 filedes 共享同一个文件数据结构。
复制一个现有的句柄,产生一个与“源句柄特性”完全一样的新句柄(也即生成一个新的句柄号,并关联到同一个设备)
要提的是这个头文件同时定义了下面三个常量:
STDERR_FILENO = 2 标准错误输出
STDIN_FILENO = 0 标准输入
STDOUT_FILENO = 1 标准输出