ZBLOG

#define _GNU_SOURCE #include #include #include #include #include #include #include ucontext_t ctx[3]; ucontext_t main_ctx; int count = 0; // hook typedef ssize_t...

你的代码实现了一个简单的文件读写操作,并使用 dlsym 函数来挂钩标准库中的 readwrite 函数,以便在进行读取和写入时打印相关信息。以下是代码的一些要点以及可能的改进:

代码要点

  1. 钩子函数

    • 通过 typedef 定义了指向原始 readwrite 函数的指针。
    • 使用 dlsym(RTLD_NEXT, "read")dlsym(RTLD_NEXT, "write") 来获取实际的系统调用。
  2. 文件打开和权限设置

    • 创建或打开一个名为 “a.txt” 的文件,并设置其权限。
  3. 数据写入和读取

    • 向文件中写入字符串 “1234567890”。
    • 读取该文件内容并存储到缓冲区中,最后打印出读取的内容。

可能的问题与建议

  1. 未重置文件指针: 在执行完写操作后,文件描述符的位置将会在字符串末尾,因此在读取之前需要将文件指针移动到开始位置。这可以通过调用 lseek(fd, 0, SEEK_SET) 来实现。例如:

    lseek(fd, 0, SEEK_SET);
    
  2. 避免过度依赖格式化输出: 在输出时,如果缓冲区没有以 null 字符结尾(如数组未完全填满),直接输出可能导致未定义行为。使用以下方法确保安全输出:

    printf("buffer: %.*s\n", (int)sizeof(buffer), buffer);
    
  3. 关闭文件描述符: 文件使用完毕后,应该调用 close(fd); 来释放资源。

  4. 错误处理: 可以增加更详细的错误处理,例如打印失败信息以帮助调试。

  5. 使用正确参数传递给 read 函数: 当你定义钩子函数时,确保你所传递的参数符合预期(例如 count 应该小于等于你分配给 buffer 的大小)。

修改后的示例代码

这是对你的原始代码进行了上述修改后的示例:

#define _GNU_SOURCE

#include <dlfcn.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>

typedef ssize_t (*read_t)(int fd, void *buf, size_t count);
read_t read_f = NULL;

typedef ssize_t (*write_t)(int fd, const void *buf, size_t count);
write_t write_f = NULL;

ssize_t read(int fd, void *buf, size_t count) {
    ssize_t ret = read_f(fd, buf, count);
    printf("read: %.*s\n", (int)ret, (char *)buf); // 输出已读字节长度的数据
    return ret;
}

ssize_t write(int fd, const void *buf, size_t count) {
    printf("write: %.*s\n", (int)count, (const char *)buf); // 输出即将写入的数据
    return write_f(fd, buf, count);
}

void init_hook(void) {
    if (!read_f) {
        read_f = dlsym(RTLD_NEXT,"read");
    }
    
    if (!write_f) {
        write_f = dlsym(RTLD_NEXT,"write");
    }
}

int main() {
    init_hook();

    int fd = open("a.txt", O_CREAT | O_RDWR | O_TRUNC , S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); // 确保每次都从头开始写
    if (fd < 0) {
        perror("Error opening file");
        return -1;
    }

    char *str = "1234567890";
    write(fd, str, strlen(str));

    lseek(fd, 0, SEEK_SET); // 移动到开头以便读取刚才写入的数据

    char buffer[128] = {0};
    read(fd, buffer,sizeof(buffer)); 

	// 打印缓冲区内容 
	printf("buffer: %.*s\n", (int)sizeof(buffer), buffer);

	close(fd); // 关闭文件描述符

	return 0;
}

这段代码将会在运行时创建一个名为 “a.txt” 的新文本文件,将字符串 "1234567890" 写入其中,然后再读取回并显示。同时,它也能够在控制台上显示读写操作的信息。


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://sdn.0voice.com/?id=6177

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?