c - 系统调用 "open"无法使用 O_CREAT 标志创建文件

标签 c linux system-calls

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

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

我发现我可以用系统调用打开文件 open可以同时打开输入文件(标志 O_RDONLY )和输出文件(标志 O_CREAT | O_WRONLY )。

输入文件工作正常。输出文件没有。

Errno 表示代码 2 =“没有这样的文件或目录”(显然,我要求创建文件)。我做错了什么?

P.S.:为了强调我正在使用系统调用,我没有调用函数 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;   
}

完整代码:

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

Screenshot of the execution

最佳答案

我在 strace 下运行了你的代码并得到:

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

即您对 O_* 标志的定义是错误的。

事实证明,不止一件事是错误的:0x0200 实际上是 O_TRUNC(不是 O_CREAT),而 0x0400 实际上是 O_APPEND(不是 O_TRUNC)。

将其更改为

#define O_CREAT 0x0040
#define O_TRUNC 0x0200

让它发挥作用。

关于c - 系统调用 "open"无法使用 O_CREAT 标志创建文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38026725/

相关文章:

linux - 神经节中的 "cpu_intr"和 "cpu_sintr"是什么意思

linux - 将数据从一台服务器迁移到另一台

javascript - V8 JavaScript 引擎可以调用外部库或函数吗?

security - 什么系统调用来阻止/允许/检查创建程序主管

shell - 系统调用、shell 命令和程序

c - fscanf (fi ,"%d %d", &used,&quota)==2 中等于 2 意味着什么?

c - 堆的交换功能似乎很奇怪

使用指针输入结构值时 scanf 函数中的混淆

c - 如何将整数转换为C中的字符?

c - 使用syscall后如何访问errno?