为什么在父进程中写重复文本?
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
”。
我正在阅读操作系统三篇文章。在完成其中一个练习时,我遇到了一个与 '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
”。