使用 O_APPEND 的 open() 不更新 EOF
open() using O_APPEND does not update EOF
我正在写一份dup()
函数(我正在为Linuxapi学习一本书)。
我有一个名为 temp.txt
的文件,其中一行包含以下字符串:Hello, World
.
代码如下:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
//NAIVE IMPLEMENTATION
int dup_t(int old) {
if(old == -1) {
errno = EBADF;
return -1;
}
int flags;
flags = fcntl(old, F_GETFL);
if(flags == - 1) {
errno = EBADF;
return -1;
}
int new;
if((new = fcntl(old, F_DUPFD)) == - 1) {
errno = EBADF;
return - 1;
}
return new;
}
int main(int argc, char *argv[]) {
if(argc == 1) {
printf("Error, no arguments given\n");
exit(-1);
}
int fd, cpfd;
if((fd = open(&argv[1][0], O_RDWR | O_APPEND)) == -1) {
printf("Error opening the file\n");
exit(-1);
}
cpfd = dup_t(fd);
if(cpfd == -1) {
printf("Error dup_t()\n");
exit(-1);
}
if(close(fd) == -1) {
printf("Error closing fd\n");
exit(-1);
}
if(write(cpfd, "kostas", 6) == - 1) {
printf("Error writting\n");
exit(-1);
}
if(close(fd) == -1) {
printf("Error closing fd\n");
exit(-1);
}
if(write(cpfd, "kostas", 6) == - 1) {
printf("Error writting\n");
exit(-1);
}
if(close(cpfd) == -1) {
printf("Error closing cpfd\n");
exit(-1);
}
}
所以,通过运行./prog temp.txt
成功,文件temp.txt
必须包含以下字符串。 Hello, WorldKostas
通过 运行 命令 cat temp.txt
我得到的输出是 Hello, World
,但是,如果我在像 nano
这样的文本编辑器上打开文件,我得到 Hello, World
(后跟一个新行,其中包含)kostas
.
为什么 cat
命令会产生错误的输出?
为什么在字符串末尾添加了一个新行 Hello, World
?
我不是在寻找解决方法,我有兴趣找出 error/problem 的原因。
文件已经更新为:
Hello, World[eol]
Kostas[no end-of-line here]
cat
会输出文件内容 exactly,不会输出最终的 eol,这是你的终端在 cat
之后显示的内容:
bash> cat xxx
Hello, World
Kostasbash>
注意:bash>
是你的提示符,有时你的提示符可能包含carrier return
,这会将光标放在行首,考虑这种情况
输出提示前:
bash> cat xxx
Hello, World
Kostas
^cursor here
运营商之后return:
bash> cat xxx
Hello, World
Kostas
^cursor here
最终输出提示:
bash> cat xxx
Hello, World
bash>
^cursor here
因此,如果文件末尾没有 eol,您的提示可能会覆盖 cat 输出的最后一行。
顺便说一句:
- 使用
vim
打开文件时,左下角会显示[noeol]表示文件末尾没有eol
- 当使用
zsh
时,如果最后一个命令最后没有输出eol,会显示%
,zsh会额外输出一个eol。
我正在写一份dup()
函数(我正在为Linuxapi学习一本书)。
我有一个名为 temp.txt
的文件,其中一行包含以下字符串:Hello, World
.
代码如下:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
//NAIVE IMPLEMENTATION
int dup_t(int old) {
if(old == -1) {
errno = EBADF;
return -1;
}
int flags;
flags = fcntl(old, F_GETFL);
if(flags == - 1) {
errno = EBADF;
return -1;
}
int new;
if((new = fcntl(old, F_DUPFD)) == - 1) {
errno = EBADF;
return - 1;
}
return new;
}
int main(int argc, char *argv[]) {
if(argc == 1) {
printf("Error, no arguments given\n");
exit(-1);
}
int fd, cpfd;
if((fd = open(&argv[1][0], O_RDWR | O_APPEND)) == -1) {
printf("Error opening the file\n");
exit(-1);
}
cpfd = dup_t(fd);
if(cpfd == -1) {
printf("Error dup_t()\n");
exit(-1);
}
if(close(fd) == -1) {
printf("Error closing fd\n");
exit(-1);
}
if(write(cpfd, "kostas", 6) == - 1) {
printf("Error writting\n");
exit(-1);
}
if(close(fd) == -1) {
printf("Error closing fd\n");
exit(-1);
}
if(write(cpfd, "kostas", 6) == - 1) {
printf("Error writting\n");
exit(-1);
}
if(close(cpfd) == -1) {
printf("Error closing cpfd\n");
exit(-1);
}
}
所以,通过运行./prog temp.txt
成功,文件temp.txt
必须包含以下字符串。 Hello, WorldKostas
通过 运行 命令 cat temp.txt
我得到的输出是 Hello, World
,但是,如果我在像 nano
这样的文本编辑器上打开文件,我得到 Hello, World
(后跟一个新行,其中包含)kostas
.
为什么 cat
命令会产生错误的输出?
为什么在字符串末尾添加了一个新行 Hello, World
?
我不是在寻找解决方法,我有兴趣找出 error/problem 的原因。
文件已经更新为:
Hello, World[eol] Kostas[no end-of-line here]
cat
会输出文件内容 exactly,不会输出最终的 eol,这是你的终端在cat
之后显示的内容:bash> cat xxx Hello, World Kostasbash>
注意:bash>
是你的提示符,有时你的提示符可能包含carrier return
,这会将光标放在行首,考虑这种情况
输出提示前:
bash> cat xxx
Hello, World
Kostas
^cursor here
运营商之后return:
bash> cat xxx
Hello, World
Kostas
^cursor here
最终输出提示:
bash> cat xxx
Hello, World
bash>
^cursor here
因此,如果文件末尾没有 eol,您的提示可能会覆盖 cat 输出的最后一行。
顺便说一句:
- 使用
vim
打开文件时,左下角会显示[noeol]表示文件末尾没有eol - 当使用
zsh
时,如果最后一个命令最后没有输出eol,会显示%
,zsh会额外输出一个eol。