03.xx write 有 O_APPEND 标志也会修改文件偏移量

首先保证 A.txt 文件是空的。然后编译运行:

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

void
perror_and_exit (const char *msg)
{
    perror (msg);
    exit (errno);
}

int
main (int argc, char **argv)
{
    int fd;
    char buf[64];

    /* 完成截断 */
    if ((fd = open ("A.txt", O_CREAT | O_WRONLY | O_TRUNC)) == -1)
        perror_and_exit ("open for truncation");
    if (close (fd) == -1)
        perror_and_exit ("close for truncation");

    if ((fd = open ("A.txt", O_APPEND | O_RDWR)) == -1)
        perror_and_exit ("open");

    /* 第一次写入 */
    if (write (fd, "nodoubtnodoubt", 14) == -1)
        perror_and_exit ("write nodoubtnodoubt");

    /* 第二次写入只能写入到末尾,是因为 O_APPEND 存在 */
    if (lseek (fd, 0, SEEK_SET) == -1)
        perror_and_exit ("lseek 64");
    if (write (fd, "lalala", 6) == -1)
        perror_and_exit ("write lalala");

    /*
     * 尽管之前调用过 lseek,但还是无法读出字符,说明 O_APPEND 模式下的 write
     * 也会更新文件偏移量
     */
    if (read (fd, buf, 16) == -1)
        perror_and_exit ("read");
    printf ("read: %s\n", buf);

    /* 再次 lseek 就能读出开头的字符 */
    if (lseek (fd, 0, SEEK_SET) == -1)
        perror_and_exit ("lseek 0");
    if (read (fd, buf, 16) == -1)
        perror_and_exit ("read");
    printf ("read: %s\n", buf);
}

最后 A.txt 文件的内容:

nodoubtnodoubtlalala

输出的内容:

read: 
read: nodoubtnodoubtla