为什么在父进程中写重复文本?

Why is write duplicating text in parent process?

我正在阅读操作系统三篇文章。在完成其中一个练习时,我遇到了一个与 'write' 系统调用相关的有趣行为。程序如下,

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <errno.h>

int main() 
{
    int fd = open("./some_file.txt", O_CREAT | O_WRONLY | O_APPEND, 0777);
    int rc =  fork();
    if (rc < 0) 
    {
        printf("Fork failed\n");
        exit(10);
    }
    else if (rc == 0) 
    {
        write(fd, "the sun shines so bright\n", 26);
    }
    else
    {
        wait(NULL);
        int e = write(fd, "it's a cold night outside \n", 36);
        if (e == -1)
        {
            printf("error writing to fd, %s", strerror(errno));
            exit(-1);
        }
    }
    return 0;
}

当父进程等待子进程完成时,这个程序的输出是,

the sun shines so bright
it's a cold night outside

这是意料之中的。但是,如果我将要写入子进程的字节数从 26 更改为 36,

write(fd, "the sun shines so bright\n", 36);

输出变为

the sun shines so bright
it's a colit's a cold night outside

_________^ 10 bytes

子进程字符串(阳光普照所以bright\n[=25=])是26字节。额外的 10 个字节导致此行为。我已经为子进程中的 write 语句尝试了不同的值,并且行为是一致的。有人可以解释为什么会这样吗?

Can someone please explain why this is happening?

对于 write(fd, "the sun shines so bright\n", 26); 只有 25 个字节,然后是不应该写入的零终止符,但是零终止符可能只是被您用来显示文件的任何内容忽略,因此它“有效” (偶然地,如果您以不同的方式显示文件并且文件中间的零终止符未被忽略,则会以某种方式中断)。

对于write(fd, "the sun shines so bright\n", 36);仍然只有25个字节,然后是不应该写入的零终止符,然后是另外10个不应该写入的垃圾字节。那个垃圾恰好是一个完全不同的字符串的开头,所以(由于运气和未定义行为的结合)它实际上写了“the sun shines so bright\n”,然后是忽略的字符串终止符,然后是“it's a col”。

对于write(fd, "it's a cold night outside \n", 36);只有26字节,然后是不应写入的零终止符,然后是不应写入的9字节垃圾。在这种情况下(由于运气和未定义行为的结合)我假设垃圾恰好是零。老实说,我很惊讶(由于运气和未定义行为的结合)它最终没有写“it's a cold night outside \n”,然后是被忽略的零终止符,然后是“error wri”。