系统调用“打开".无法使用O_CREAT标志创建文件 [英] system call "open" cannot create file with O_CREAT flag
问题描述
我必须使用linux的系统调用来完成练习:
I've got to complete an exercise using linux's system calls:
- 打开文件"testinput.txt"(已经存在于工作目录中,不能为空)
- 打开文件testoutput.txt"(不在工作目录中)
- 在testoutput中复制testinput的内容
- 关闭两个文件
我发现可以通过系统调用打开文件 open
可以同时打开输入文件(标志 O_RDONLY
)和输出文件(标志 O_CREAT |O_WRONLY
).
I found that I can open the file with system call open
can both open the input file (flag O_RDONLY
) and the output file (flag O_CREAT | O_WRONLY
).
输入文件正常工作.输出文件没有.
The input file works correctly. The output file doesn't.
Errno说代码2 =没有这样的文件或目录"(显然,我要求创建文件).我在做什么错了?
Errno says code 2 = "No such file or direcory" (obviously, I asked to create the file). What am I doing wrong?
PS:要突出显示我正在使用syscalls,我不是在调用函数 open(...)
,而是在 syscall(SYS_OPEN,...)
>
P.S.: To highlight I'm using syscalls, I'm not calling function open(...)
but syscall(SYS_OPEN, ...)
outFileDesc = syscall(SYS_OPEN, "testoutput.txt", O_WRONLY | O_TRUNC | O_CREAT, 438);
if(outFileDesc == -1) {
int code = errno;
// gdb used here -> print code -> 2
char str[] = "Unable to open \"testoutput.txt\"\n";
syscall(SYS_WRITE, FILE_DESC_STDOUT, str, sizeof(str)/sizeof(char));
syscall(SYS_CLOSE, inFileDesc);
syscall(SYS_EXIT, 1);
return 1;
}
整个代码:
#include <unistd.h>
#include <sys/syscall.h>
#include <errno.h>
/* file flags fcntl.h */
#define O_RDONLY 0x0000 /* open for reading only */
#define O_WRONLY 0x0001 /* open for writing only */
#define O_CREAT 0x0200 /* create if nonexistant */
#define O_TRUNC 0x0400 /* truncate to zero length */
#define FILE_DESC_STDOUT 1
#define SYS_EXIT 1
#define SYS_READ 3
#define SYS_WRITE 4
#define SYS_OPEN 5
#define SYS_CLOSE 6
#define IN_MESSAGE_LEN 9
#define OUT_MESSAGE_LEN 9
char inBuffer[IN_MESSAGE_LEN];
char outBuffer[OUT_MESSAGE_LEN];
int main (int argc, char *argv[])
{
int inFileDesc, outFileDesc;
// Apertura fine di input
inFileDesc = syscall(SYS_OPEN, "testinput.txt", O_RDONLY, 438);
if(inFileDesc == -1) {
char str[] = "Unable to open \"testinput.txt\"\n";
syscall(SYS_WRITE, FILE_DESC_STDOUT, str, sizeof(str)/sizeof(char));
syscall(SYS_EXIT, 1);
return 1;
}
// Apertura fine di output
outFileDesc = syscall(SYS_OPEN, "testoutput.txt", O_WRONLY | O_TRUNC | O_CREAT, 438);
if(outFileDesc == -1) {
int code = errno;
char str[] = "Unable to open \"testoutput.txt\"\n";
syscall(SYS_WRITE, FILE_DESC_STDOUT, str, sizeof(str)/sizeof(char));
syscall(SYS_CLOSE, inFileDesc);
syscall(SYS_EXIT, 1);
return 1;
}
// Travaso contenuto file di input in file di output
int read, i;
while((read = syscall(SYS_READ, inFileDesc, inBuffer, IN_MESSAGE_LEN)) != 0) {
for(i = 0; i < IN_MESSAGE_LEN; i++) {
outBuffer[i] = inBuffer[i];
}
syscall(SYS_WRITE, outFileDesc, outBuffer, OUT_MESSAGE_LEN);
}
syscall(SYS_CLOSE, inFileDesc);
syscall(SYS_CLOSE, outFileDesc);
syscall(SYS_EXIT, 0);
return 0;
}
推荐答案
我在 strace
并得到:
I ran your code under strace
and got:
...
open("testinput.txt", O_RDONLY) = 3
open("testoutput.txt", O_WRONLY|O_TRUNC|O_APPEND) = -1 ENOENT (No such file or directory)
// ^^^^^^^^
即您对 O _ *
标志的定义是错误的.
I.e. your definition of the O_*
flags is wrong.
事实证明,不只一个错误: 0x0200
实际上是 O_TRUNC
(不是 O_CREAT
),而 0x0400
实际上是 O_APPEND
(不是 O_TRUNC
).
As it turns out, there's more than one thing wrong: 0x0200
is actually O_TRUNC
(not O_CREAT
), and 0x0400
is actually O_APPEND
(not O_TRUNC
).
更改为
#define O_CREAT 0x0040
#define O_TRUNC 0x0200
使其正常工作.
这篇关于系统调用“打开".无法使用O_CREAT标志创建文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!