系统调用“打开".无法使用O_CREAT标志创建文件 [英] system call "open" cannot create file with O_CREAT flag

查看:56
本文介绍了系统调用“打开".无法使用O_CREAT标志创建文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须使用linux的系统调用来完成练习:

I've got to complete an exercise using linux's system calls:

  1. 打开文件"testinput.txt"(已经存在于工作目录中,不能为空)
  2. 打开文件testoutput.txt"(不在工作目录中)
  3. 在testoutput中复制testinput的内容
  4. 关闭两个文件

我发现可以通过系统调用打开文件 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆