命名管道的随机访问替代方案
Random access alternative to named pipes
有没有办法创建一个 "file"(即文件系统中的某个点),然后可以由任何程序将其作为常规文件打开,但是 reading/writing 它会转到一个程序而不是磁盘?命名管道似乎满足所有要求,除了它只允许串行文件访问。
我目前对 *nix 类型的系统很感兴趣,但很想知道在任何 OS/file 系统上都有这样的系统。
也许你可以使用 mmap 创建一个共享内存,一个后端程序持有这个内存。其他程序可以打开这个'file'并随机read/write到后端程序
我没试过,但我认为它可以工作!
这是一个实现:
demon.c:
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <unistd.h>
#include <fcntl.h>
#include <assert.h>
#include <string.h>
#include <errno.h>
void map_file(const char *f) {
int fd = open(f, O_CREAT|O_RDWR, 0666);
if (fd < 0) {
perror("fd open error\n");
exit(-1);
}
char *addr = (char *)mmap(NULL, 10, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (addr == MAP_FAILED) {
exit(-1);
}
int i;
for (i = 0; i != 10; ++i) {
addr[i] = '0' + i;
}
while (1) {
for (i = 0; i != 10; ++i) {
if (addr[i] != '0' + i) {
printf("addr[%d]: %c\n", i, addr[i]);
}
}
sleep(1);
}
}
int main()
{
map_file("/dev/mem");
return 0;
}
cli.c:
#include <sys/mman.h>
#include <assert.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
int main() {
const char *f = "/dev/mem";
int fd = open(f, O_RDWR, 0666);
assert(fd >= 0);
lseek(fd, rand() % 10, SEEK_SET);
write(fd, "X", 1);
close(fd);
return 0;
}
我们将“/dev/mem”中的 10 字节内存映射到我们的恶魔程序。 cli 将此文件作为常规文件打开,并在随机地址中写入一个字节。当然,您可以映射任何其他文件而不是 /dev/mem,但您需要在 mmap 之前从常规文件中 'alloc' 一些字节。例如:
fd = open("/path/to/myfile", O_CREAT|O_RDWR, 0666);
write(fd, "0123456789", 10); // 'allocate' 10 bytes from regular file
addr = (char *)mmap(NULL, 10, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
我认为提问者指的是提供文件的程序挂钩程序 using/accessing/opening 文件的所有访问的特殊情况,否则提供者程序将无法控制用户程序是什么 reading/writing 何时何地。在这种情况下,提供者程序可以简单地以允许任何其他程序并发 reads/writes 的模式打开标准文件。
在 hook-case 中,研究以下解决方案:libFUSE、BUSE、python-fuse、scriptfs、NBD、NBDkit。
有没有办法创建一个 "file"(即文件系统中的某个点),然后可以由任何程序将其作为常规文件打开,但是 reading/writing 它会转到一个程序而不是磁盘?命名管道似乎满足所有要求,除了它只允许串行文件访问。
我目前对 *nix 类型的系统很感兴趣,但很想知道在任何 OS/file 系统上都有这样的系统。
也许你可以使用 mmap 创建一个共享内存,一个后端程序持有这个内存。其他程序可以打开这个'file'并随机read/write到后端程序
我没试过,但我认为它可以工作!
这是一个实现:
demon.c:
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <unistd.h>
#include <fcntl.h>
#include <assert.h>
#include <string.h>
#include <errno.h>
void map_file(const char *f) {
int fd = open(f, O_CREAT|O_RDWR, 0666);
if (fd < 0) {
perror("fd open error\n");
exit(-1);
}
char *addr = (char *)mmap(NULL, 10, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (addr == MAP_FAILED) {
exit(-1);
}
int i;
for (i = 0; i != 10; ++i) {
addr[i] = '0' + i;
}
while (1) {
for (i = 0; i != 10; ++i) {
if (addr[i] != '0' + i) {
printf("addr[%d]: %c\n", i, addr[i]);
}
}
sleep(1);
}
}
int main()
{
map_file("/dev/mem");
return 0;
}
cli.c:
#include <sys/mman.h>
#include <assert.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
int main() {
const char *f = "/dev/mem";
int fd = open(f, O_RDWR, 0666);
assert(fd >= 0);
lseek(fd, rand() % 10, SEEK_SET);
write(fd, "X", 1);
close(fd);
return 0;
}
我们将“/dev/mem”中的 10 字节内存映射到我们的恶魔程序。 cli 将此文件作为常规文件打开,并在随机地址中写入一个字节。当然,您可以映射任何其他文件而不是 /dev/mem,但您需要在 mmap 之前从常规文件中 'alloc' 一些字节。例如:
fd = open("/path/to/myfile", O_CREAT|O_RDWR, 0666);
write(fd, "0123456789", 10); // 'allocate' 10 bytes from regular file
addr = (char *)mmap(NULL, 10, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
我认为提问者指的是提供文件的程序挂钩程序 using/accessing/opening 文件的所有访问的特殊情况,否则提供者程序将无法控制用户程序是什么 reading/writing 何时何地。在这种情况下,提供者程序可以简单地以允许任何其他程序并发 reads/writes 的模式打开标准文件。
在 hook-case 中,研究以下解决方案:libFUSE、BUSE、python-fuse、scriptfs、NBD、NBDkit。