了解文件截断

时间:2015-09-22 13:09:57

标签: c linux file unix truncate

引自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;
}

我不明白这种行为是如何可行的,以及文件截断如何阻止这种行为发生。有人可以解释一下吗?

感谢您的回答!

2 个答案:

答案 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。