简体   繁体   English

系统调用“打开”无法创建带有O_CREAT标志的文件

[英]system call “open” cannot create file with O_CREAT flag

I've got to complete an exercise using linux's system calls: 我必须使用linux的系统调用来完成练习:

  1. open the file "testinput.txt" (already present in the working directory, not empty) 打开文件“ testinput.txt”(已经存在于工作目录中,不能为空)
  2. open the file "testoutput.txt" (not present in the working directory) 打开文件“ testoutput.txt”(工作目录中不存在)
  3. copy the content of testinput in testoutput 将testinput的内容复制到testoutput中
  4. close both files 关闭两个文件

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 ). 我发现可以在系统调用open文件,可以同时打开输入文件(标志O_RDONLY )和输出文件(标志O_CREAT | O_WRONLY )。

The input file works correctly. 输入文件正常工作。 The output file doesn't. 输出文件没有。

Errno says code 2 = "No such file or direcory" (obviously, I asked to create the file). Errno说代码2 =“没有这样的文件或目录”(显然,我要求创建文件)。 What am I doing wrong? 我究竟做错了什么?

PS: To highlight I'm using syscalls, I'm not calling function open(...) but syscall(SYS_OPEN, ...) PS:强调我正在使用syscalls,我不是在调用函数open(...)而是在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;   
}

Whole code: 整个代码:

#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;
}

执行截图

I ran your code under strace and got: 我在strace下运行您的代码并得到:

...
open("testinput.txt", O_RDONLY)         = 3
open("testoutput.txt", O_WRONLY|O_TRUNC|O_APPEND) = -1 ENOENT (No such file or directory)
//                                      ^^^^^^^^

Ie your definition of the O_* flags is wrong. 也就是说,您对O_*标志的定义是错误的。

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 ). 事实证明,有不止一个错误: 0x0200实际上是O_TRUNC (不是O_CREAT ),而0x0400实际上是O_APPEND (不是O_TRUNC )。

Changing it to 更改为

#define O_CREAT 0x0040
#define O_TRUNC 0x0200

makes it work. 使它工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM