Amm*_*san 2 c linux mmap system-calls
我正在尝试创建一个空文件(如果它不存在)。而不是使用 mmap() 映射它,这样我就可以将它传递给我的其他程序进行写入。我不确定 mmap 的哪些参数适合空文件。我的代码适用于非空文件,但如果文件为空,则会出现错误“无效参数”
代码program1(如果不存在则仅创建一个空文件)
int i;
int fd = open("/home/sungmin/dummy_programs/dummy.txt", O_RDONLY | O_CREAT, 0777);
char *pmap;
pid_t child;
if (fd == -1)
{
perror("Error opening file for writing");
exit(EXIT_FAILURE);
}
struct stat fileInfo = {0};
if (fstat(fd, &fileInfo) == -1)
{
perror("Error getting the file size");
exit(EXIT_FAILURE);
}
/*if (fileInfo.st_size == 0)
{
fprintf(stderr, "Error: File is empty, nothing to do\n");
exit(EXIT_FAILURE);
}*/
pmap = mmap(0, fileInfo.st_size, PROT_READ | PROT_EXEC , MAP_ANONYMOUS, fd, 0);
if (pmap == MAP_FAILED)
{
close(fd);
perror("Error mmapping the file");
exit(EXIT_FAILURE);
}
/* Calling fork function */
if((child=fork())==0){
printf("Iam Child process\n\n");
static char *argv[]={"This is some sample text. I need to write this text in my dummy file.","/home/sungmin/dummy_programs/dummy.txt",NULL};
execv("/home/sungmin/dummy_programs/pro2",argv);
exit(127);
}
else {
printf("Iam parent, waiting for child process to exit\n\n");
waitpid(child,0,0);
printf("Existing parent\n\n");
}
/* Don't forget to free the mmapped memory*/
if (munmap(pmap, fileInfo.st_size) == -1)
{
close(fd);
perror("Error un-mmapping the file");
exit(EXIT_FAILURE);
}
/* Un-mmaping doesn't close the file, so we still need to do that.*/
close(fd);
Run Code Online (Sandbox Code Playgroud)
代码program2(打开与program1相同的文件并写入program1传递的文本)
size_t i;
int fd;
char *pmap;
pid_t child;
struct stat fileInfo = {0};
const char *text = argv[0];
fd = open(argv[1], O_RDWR | O_CREAT | O_TRUNC, (mode_t)0600);
if (fd == -1)
{
perror("Error opening file for writing");
exit(EXIT_FAILURE);
}
size_t textsize = strlen(text) + 1; // + \0 null character
if (lseek(fd, textsize-1, SEEK_SET) == -1)
{
close(fd);
perror("Error calling lseek() to 'stretch' the file");
exit(EXIT_FAILURE);
}
if (write(fd, "", 1) == -1)
{
close(fd);
perror("Error writing last byte of the file");
exit(EXIT_FAILURE);
}
pmap = mmap(0, textsize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (pmap == MAP_FAILED)
{
close(fd);
perror("Error mmapping the file");
exit(EXIT_FAILURE);
}
/* Writting users text to file */
for (i = 0; i < textsize; i++)
{
pmap[i] = text[i];
}
// Write it now to disk
if (msync(pmap, textsize, MS_SYNC) == -1)
{
perror("Could not sync the file to disk");
}
/* Don't forget to free the mmapped memory*/
if (munmap(pmap, textsize) == -1)
{
close(fd);
perror("Error un-mmapping the file");
exit(EXIT_FAILURE);
}
/* Un-mmaping doesn't close the file, so we still need to do that.*/
close(fd);
Run Code Online (Sandbox Code Playgroud)
您需要truncate在创建文件后在映射之前使用它来扩展文件长度。
是的,函数名称听起来不对,但truncate实际上可以将文件长度设置为任意数字。请务必使用 4K 的倍数以获得最佳效果。
然后,如果您希望保持映射打开以查看程序 1 和 2 之间的数据,则需要在程序 1 中删除 ANONYMOUS 并使用 MAP_SHARED 进行映射。未共享的映射将不会显示其他程序所做的更改。或者,如果必须从磁盘重新加载,也可能会这样。这很奇怪,不要混合共享和非共享映射。
一旦您将程序 1 更改为使用truncate,请将其lseek和write代码从程序 2 中取出。该文件已由程序 1 创建并扩展。
| 归档时间: |
|
| 查看次数: |
6704 次 |
| 最近记录: |