C - 文件 i/o 的一些荒谬错误

标签 c linux archlinux

我有一个类似于 cp 的简单程序,它将内容从一个文件复制到另一个文件,包括漏洞。语义简单,实现简单,主要部分如下。问题是,如果我在没有下面标记的行的情况下编译并运行 (GCC 4.7.1 Arch Linux),它会用随机字节序列填充第二个文件几秒钟,并以段错误结束。但是,如果我插入标记的行(它只是将当前写入的字节数输出到 tty - 一切正常)。如果我使用例如printf("Hello World!\n") 而不是它,它仍然是坏的。

这是怎么回事?某些与程序语义没有任何关系的库函数如何导致此错误?

#include "tlpi_hdr.h" //declares errExit and usageErr
#include <malloc.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>

#define BUF_SIZE 1024

int main(int argc, char **argv)
{
    if ( argc != 3 )
        usageErr("cp_self source dest");
    int fd_source, fd_dest, bytes;
    char *buf, *cur;
    buf = malloc(BUF_SIZE);
    FILE *str;

    if ( ( fd_source = open(argv[1], O_RDONLY) ) == -1 )
        errExit("open(%s)", argv[1]);
    if ( ( fd_dest = open(argv[2], O_WRONLY | O_TRUNC | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO) ) == -1 )
        errExit("open(%s)", argv[2]);
    if ( ( str = fdopen(fd_dest, "w") ) == NULL )
        errExit("fdopen(%d, 'w')", fd_dest);
    while ( ( bytes = read(fd_source, buf, BUF_SIZE) ) != 0 )
    {
        int dbg_cntr = 0;
        cur = buf;
        while ( cur != buf + bytes )
        {
            //printf("%d\n", dbg_cntr++); this line
            if ( *cur == '\0' )
            {
                if ( fflush(str) != 0 )
                    errExit("fflush(%d)", str);
                if ( lseek(fd_dest, 1, SEEK_CUR) == (off_t) -1 )
                    errExit("lseek(%d, 1, SEEK_CUR)", fd_dest);
            }
            else
            {
                if ( fprintf(str, "%c", *cur) != 1 )
                    errExit("fprintf(%d, %c)", str, *cur);
            }
            ++cur;
        }
    }
}

添加了整个代码。

最佳答案

read() 将在出错时返回 -1:在这种情况下,buf + bytes 将小于 cur 并且你将有一个无限循环,直到 cur 指向一些你不允许读取的内存,从而导致分段违规。

关于C - 文件 i/o 的一些荒谬错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12010814/

相关文章:

c++ - 将数组元素添加到链表中

c - 理解gnu libc的strcmp函数

c++ - 尝试连接到 tcp 套接字时连接被拒绝 (linux)

c++ - GNU/Linux 中 "drawing"抽象的绝对最低级别是什么?

R v3.4.0-2 在 Arch 上无法找到 libgfortran.so.3

c++ - 如何知道程序调用了库的哪些函数

c - C中的链表实现

linux - 创建 Cron 作业以在 QNAP NAS 上应用权限

linux - GitHub Actions 意外的 bash 可读测试结果

mysql - 运行 SQL 脚本出现语法错误