简体   繁体   中英

Understanding File Truncation

Quoting from Advanced Programming in the UNIX Environnement (page 505), Section 13.6:

We need to truncate the file, because the previous instance of the daemon might have had a process ID larger than ours, with a larger string length. For examples , if the previous instance of the daemon was process ID 12345, and the new instance is process ID 9999, when we write the process ID to the file, we will be left with 99995 in the file. Truncating the file prevents data from the previous daemon appearing as if it applies to the current daemon.

This comment was made on this function:

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

I don't understand how is this behavior possible, and how file truncation prevent that behavior from happening. Could somebody explain this?

Thanks for answering!

In the above example, the file is initially 5 bytes long. When you open it for writing, and write the string "9999" to it without truncating, it will just overwrite the first 4 bytes, and leave the 5th byte in place. Hence the file will read "99995". Truncating sets the file length to 0, effectively erasing the previous content.

Hellmar has already provided the answer to your question -- but in the interest of shortening the code (who doesn't like code golf?), you could simplify the open call to:

already_running(void)
{
    int fd;
    char buf[16];
    fd = open(LOCKFILE, O_RDWR|O_CREAT|O_TRUNC, LOCKMODE);
    ...

The addition of O_TRUNC to the flags will cause the file to be truncated. http://linux.die.net/man/2/open

If the file already exists and is a regular file and the open mode allows writing (ie, is O_RDWR or O_WRONLY) it will be truncated to length 0.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM