引自Advanced Programming in the UNIX Environnement
(第505页),第13.6节:
我们需要截断文件,因为前一个实例 守护进程可能有一个比我们更大的进程ID 字符串长度。例如,如果是守护进程的前一个实例 是进程ID 12345,新实例是进程ID 9999,当我们 将进程ID写入文件,我们将留下99995 文件。截断文件会阻止来自前一个守护程序的数据 看起来好像它适用于当前的守护进程。
此评论是关于此功能的:
already_running(void)
{
int fd;
char buf[16];
fd = open(LOCKFILE, O_RDWR|O_CREAT, LOCKMODE);
if (fd < 0) {
syslog(LOG_ERR, "can't open %s: %s", LOCKFILE, strerror(errno));
exit(1);
}
if (lockfile(fd) < 0) {
if (errno == EACCES || errno == EAGAIN) {
close(fd);
return(1);
}
syslog(LOG_ERR, "can't lock %s: %s", LOCKFILE, strerror(errno));
exit(1);
}
ftruncate(fd, 0);
sprintf(buf, "%ld", (long)getpid());
write(fd, buf, strlen(buf)+1);
return 0;
}
我不明白这种行为是如何可行的,以及文件截断如何阻止这种行为发生。有人可以解释一下吗?
感谢您的回答!
答案 0 :(得分:5)
在上面的示例中,文件最初为5个字节。当你打开它进行写入,并在不截断的情况下将字符串“9999”写入其中时,它将覆盖前4个字节,并保留第5个字节。因此该文件将显示为“99995”。截断将文件长度设置为0,有效地删除了以前的内容。
答案 1 :(得分:1)
Hellmar已经为您的问题提供了答案 - 但为了缩短代码(谁不喜欢代码高尔夫?),您可以简化公开呼叫:
already_running(void)
{
int fd;
char buf[16];
fd = open(LOCKFILE, O_RDWR|O_CREAT|O_TRUNC, LOCKMODE);
...
向标志添加 O_TRUNC 将导致文件被截断。 http://linux.die.net/man/2/open
如果文件已存在并且是常规文件和打开模式 允许写入(即,是O_RDWR或O_WRONLY)它将被截断为 长度0。