添加以前的作业
This commit is contained in:
197
exp0.5/task53.c
Normal file
197
exp0.5/task53.c
Normal file
@@ -0,0 +1,197 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
Reference in New Issue
Block a user