#include #include #include #include #include #include #include #include #define INTERVAL_SEC 10 #define LOG_FILE "log" static unsigned int compute_hash(const char *data, size_t len) { unsigned int hash =0; const unsigned char *p = (const unsigned char *)data; size_t i,n = len /4; for ( i = 0; i < n; i++) { unsigned int val = (unsigned int)p[i * 4] | ((unsigned int)p[i * 4 + 1] << 8) | ((unsigned int)p[i * 4 + 2] << 16) | ((unsigned int)p[i * 4 + 3] << 24); hash += val; } size_t rem = len % 4,base = n*4; for ( i = 0; i < rem; i++) { hash += (unsigned int)p[base + i]; } return hash; } static char *read_file(const char *path,size_t *out_len) { int fd = open(path,O_RDONLY); if (fd < 0) { return NULL; } off_t size = lseek(fd,0,SEEK_END); if (size < 0) { close(fd); return NULL; } lseek(fd,0,SEEK_SET); char *buf = malloc((size_t)size + 1); if (!buf) { close(fd); return NULL; } ssize_t n = read(fd,buf,(size_t)size); if (n < 0) { free(buf); close(fd); return NULL; } buf[n] = '\0'; *out_len = (size_t)n; close(fd); return buf; } static void write_log(unsigned int hash) { FILE *fp = fopen(LOG_FILE,"a"); if (!fp) { return; } time_t now = time(NULL); struct tm *tm_info = localtime(&now); char time_str[20]; strftime(time_str,sizeof(time_str),"%Y-%m-%d %H:%M:%S",tm_info); fprintf(fp,"%s hash=%u\n",time_str,hash); fclose(fp); } static void daemonize(void) { pid_t pid = fork(); if (pid < 0) { exit(1); } if (pid > 0) { exit(0); } setsid(); umask(0); close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); } int main(int argc,char *argv[]) { //自检模式 if (argc > 1 && strcmp(argv[1],"test") == 0) { /* 测试1: 不同内容应产生不同hash值 */ printf("自检模式\n"); const char *test_str = "Hello, World!"; unsigned int h1 = compute_hash(test_str,strlen(test_str)); const char *test_str2 = "Hello, world!"; // 注意 'W' 和 'w' unsigned int h2 = compute_hash(test_str2,strlen(test_str2)); printf("测试1: hash1=%u, hash2=%u\n",h1,h2); if (h1 != h2) printf("通过: 不同内容 -> 不同hash值\n"); else printf("失败: 不同内容应产生不同的hash值\n"); /* 测试2: 相同内容应产生相同hash值 */ unsigned int h3 = compute_hash(test_str,strlen(test_str)); printf("测试2: hash3=%u\n",h3); if (h1 == h3) printf("通过: 相同内容 -> 相同hash值\n"); else printf("失败: 相同内容应产生相同的hash值\n"); /* 测试3: 读取自身并计算hash */ size_t len; char *self = read_file("task53.c",&len); if (self) { unsigned int hself = compute_hash(self,len); printf("测试3: 自身hash=%u, 文件大小=%zu字节\n",hself,len); free(self); } return 0; } /* * 守护进程模式 * -f 表示前台运行(不调用daemonize), 便于测试 * 第二个参数可指定检查间隔秒数 */ int foreground = (argc > 1 && strcmp(argv[1],"-f") == 0); int interval = INTERVAL_SEC; if (argc > 2) interval = atoi(argv[2]); if (interval <= 0) interval = INTERVAL_SEC; if (!foreground) { daemonize(); } size_t len; char *prev_data = read_file("test.log",&len); if (!prev_data) return 1; unsigned int prev_hash = compute_hash(prev_data,len); while (1) { sleep(interval); size_t cur_len; char *cur_data = read_file("test.log",&cur_len); if (!cur_data) { continue; } unsigned int cur_hash = compute_hash(cur_data,cur_len); if (cur_hash != prev_hash) { write_log(cur_hash); free(prev_data); prev_data = cur_data; prev_hash = cur_hash; } else { free(cur_data); } } free(prev_data); return 0; }