复制文件失败,EBADF 关闭输出文件描述符

标签 c linux linux-kernel system-calls

所以我正在阅读一本过时的小书(2010 年),我正在尝试使用 Linux 系统调用复制一个文件。这就是我所拥有的:

注意:忽略tlpi_hdr.herror_functions.h,它们定义了errExit()fatal() 和其他一些,他们只是打印错误并退出。

#include <stdio.h>
#include <fcntl.h>

#include "lib/tlpi_hdr.h"
#include "lib/error_functions.h"

#ifndef BUF_SIZE
#define BUF_SIZE 1024
#endif

int main(int argc, char *argv[])
{
    int inputFd, outputFd, openFlags;
    mode_t filePerms;
    ssize_t numRead;
    char buf[BUF_SIZE];

    if (argc != 3 || strcmp(argv[1], "--help") == 0) {
        usageErr("%s old-file new-file\n", argv[0]);
    }

    inputFd = open(argv[1], O_RDONLY);

    if (inputFd == -1) {
        errExit("Opening file %s", argv[1]);
    }

    openFlags = O_CREAT | O_WRONLY | O_TRUNC;
    filePerms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;

    outputFd = open(argv[2], openFlags, filePerms);

    if (outputFd == -1) {
        errExit("Opening file for writing %s", argv[1]);
    }

    while ((numRead = read(inputFd, buf, BUF_SIZE)) > 0) {

        if (write(outputFd, buf, numRead) != numRead))
            fatal("I/O Error");

        if (numRead == -1)
            fatal("Reading error");

    }

    if (close(outputFd == -1))
        errExit("close input");
    if (close(inputFd == -1))
        errExit("close output");

    return EXIT_SUCCESS;
}

我无法通过 EBADF Bad file descriptor 关闭输出文件描述符:

thinkpad :: ~/.tlpi % ./cp.o a b                                                                                                                                                 
ERROR [EBADF Bad file descriptor] close output

文件复制得很好,但是:

thinkpad :: ~/.tlpi % sha1sum a                                                                                                                                   
40a925a93e149ac53d2630cde8adeb63b8134b29  a
thinkpad :: ~/.tlpi % sha1sum b                                                                                                                                                  
40a925a93e149ac53d2630cde8adeb63b8134b29  b
thinkpad :: ~/.tlpi %

为什么?

最佳答案

让我们仔细看看您的 close 调用:

close(outputFd == -1)

此处您将 ​​outputFd 与值 -1 进行比较。其结果是一个 bool 值,在 C 中将是 01。这恰好是标准输入或标准输出,具体取决于结果。不是您描述的应该关闭的文件。

我猜你的意思是

if (close(outputFd) == -1)

关于复制文件失败,EBADF 关闭输出文件描述符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38523098/

相关文章:

linux - grep ping 输出的持续时间

linux-kernel - Linux 内核模块 - 创建 proc 文件 - proc_root 未声明的错误

c - 从符号表中读取变量的类型、地址、大小。这是使用 gnu 工具(如 gmake 或 gcc)构建的

c - 在从 Linux 套接字发送/接收数据包后访问辅助数据时,在哪些情况下 msg_controllen 可以为 0?

c++ - 如何使用 msgfmt 验证格式字符串中的位置符号占位符?

c - C 中带有++ 运算符的语句的短路评估

c - 快速调用短函数中动态内存请求的最佳方式

c++ - 存储机器数据的最佳 NoSQL 方式?

linux - Registered I/O 在 Unix/Linux 中的等价物是什么?

node.js - 我无法运行 npm install