Общие сведения об усечении файлов

Цитирование из Advanced Programming in the UNIX Environnement (стр. 505), раздел 13.6:

Нам нужно усечь файл, потому что предыдущий экземпляр демона мог иметь идентификатор процесса больше нашего, с большей длиной строки. Например, если предыдущим экземпляром демона был идентификатор процесса 12345, а новый экземпляр – это идентификатор процесса 9999, когда мы записываем идентификатор процесса в файл, мы остаемся с файлом 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; } 

Я не понимаю, как это поведение возможно, и как усечение файлов предотвращает такое поведение. Может ли кто-нибудь объяснить это?

Спасибо за ответы!

В приведенном выше примере файл изначально имеет длину 5 байтов. Когда вы открываете его для записи и записываете в него строку «9999» без усечения, он просто перезаписывает первые 4 байта и оставляет 5-й байт на месте. Следовательно, файл будет читать «99995». Усечение задает длину файла 0, эффективно стирая предыдущий контент.

Хеллмар уже дал ответ на ваш вопрос, но в интересах сокращения кода (который не любит кодовое гольф?), Вы можете упростить открытый вызов:

 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.