我需要在 mmap 中使用临时文件中的整数文件描述符。如果在仍然符合标准的情况下没有简单的方法来做到这一点,那么这种需求可能需要改变。
我最初使用以下方法获得了 FILE 流:
FILE *tmpfile();
然后用...
int fileno(FILE foo);
一切都很好,直到我在 fileno 的手册页中注意到以下内容。
CONFORMING TO
The functions clearerr(), feof(), and ferror() conform to C89 and C99.
即fileno不是 c99 的一部分。我在网上查看了一种获取临时文件名或其文件描述符的简单方法,该方法在使用时不会引发错误
-std=c99 -pedantic
到目前为止,我发现的最好的事情是:
http://www.di-mgt.com.au/c_function_to_create_temp_file.html
我很想知道其他人正在做什么来解决这个问题,是否有一个我在某处遗漏的手册页或者我可以在 c99 中使用但我忽略的明显内容?
更新:我写了一个小测试程序来看看我哪里出错了。请原谅缺乏错误检查,我试图保持简短。我在 Debian 机器上使用 clang 和 gcc 运行了它:
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <assert.h>
#include <sys/mman.h>
int main(int argc, const char* const argv[])
{
const char *fname = argv[1];
/*
FILE *stream = fopen("foo", "wb+");
-std=c99 -pedantic fails on fileno
int fd = fileno(stream);
*/
int fd ;
if((fd = open(fname, O_RDWR| O_CREAT, 0644)) < 0) {
fprintf(stderr, "fd=%i, failed: %s\n",fd, strerror (errno));
exit(EXIT_FAILURE);
}
size_t fsize = 27;
char *buf;
lseek (fd, fsize - 1, SEEK_SET);
write (fd, "", 1);
lseek (fd, 0, SEEK_SET);
buf = mmap(0, fsize, PROT_WRITE, MAP_SHARED, fd, 0);
size_t i = 0;
for(i = 0; i < fsize; i++) {
buf[i] = i % 26 + 97;
}
buf[26] = '\n';
munmap(buf, fsize);
close(fd);
return argc;//Avoid warnings about unused variables
}
使用 clang 或 gcc 运行它,注意命令开头的rm -f 。
rm -f foo mmap; clang -Wall -Wextra -std=c99 -pedantic-errors -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition mmap.c -o mmap;./mmap foo;cat foo|wc -c
rm -f foo mmap; gcc -Wall -Wextra -std=c99 -pedantic-errors -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition mmap.c -o mmap;./mmap foo;cat foo|wc -c
这很有效,这意味着我错过了有关使用 -std=c99 -pedantic 的一些信息,因为当我尝试包含任何非标准标头时,我希望它会惨遭失败,即在这种情况下,我会预料到尝试包含这些标头时会出现错误。 ..
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
我很想知道为什么上述程序会编译,即在标题中设置的东西会关闭警告还是我在滥用 gcc?