0

我正在编写一个覆盖一些系统调用的共享库。其中包括read(int fd, void *buf, size_t count)系统调用。这个库当然是在用户空间中。

所以,在我的库中,我正在捕捉read()来自应用程序的调用(用于LD_PRELOAD预加载我的库),做很多事情,并在某些时候将数据写入应用程序缓冲区(void *buf)。

有没有办法让我检查整个应用程序缓冲区是否可写?

大多数时候这不是问题,但我遇到过编写得很糟糕的应用程序,以至于他们会在调用中发布只读缓冲区,当我使用他们的缓冲区read()执行 a 时,导致我的代码出现段错误memcpy()目的地,这是有道理的,当然。

注意 1:我目前正在查看内核在实际sys_read()中是如何处理这种情况的,fs/read_write.c但这并不是那么容易理解。

注意 2:该解决方案应尽可能少地增加开销。

4

2 回答 2

1

尝试这个:

int fd = open("/dev/zero", O_RDONLY);
ssize_t ret = read(fd, dest, amt_to_write);
int err = errno;
close(fd);
if (ret<0 && err==EFAULT) ...
于 2012-12-05T19:28:00.163 回答
0

这是@R 的一个调整。响应以减轻性能影响。

没有必要一直打开和关闭 /dev/zero。只需打开一次并保持打开状态。然后,每次尝试读取时,只需读取一个字节即可确定缓冲区是否可写。

#include <sys/types.h>
#include <sys/fcntl.h>
#include <unistd.h>   

int                
check_writable(char *buf)
{                         
    static int fd;
    int r;

    if (fd == 0) {
            fd = open("/dev/zero", O_RDONLY);
    }

    r = read(fd, buf, 1);

    if (r != 1) {
            return(0);
    }

    return(1);
}             


int
main()
{  
    char *s, wr[8], *rd = "read-only buf";
    int j, r;

    for (j = 0; j < 2; j++) {
        if (j == 0) {
            s = rd;
        }
        else {
            s = wr;
        }

        r = check_writable(s);
        if (r == 0) {
            printf("read-only buffer\n");
        }
        else {
            printf("writable buffer\n");
        }
    }
}
于 2012-12-06T22:01:32.977 回答