0

我需要在 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?

4

2 回答 2

4

你无法达到你想要的。

的文档-pedantic说:

发出严格的 ISO C 和 ISO C++ 要求的所有警告;拒绝所有使用禁止扩展的程序,以及其他一些不遵循 ISO C 和 ISO C++ 的程序。对于 ISO C,遵循使用的任何 -std 选项指定的 ISO C 标准版本。

整数文件描述符不是 C 标准的一部分。他们来自 POSIX。此外,mmapC 标准中没有,它也来自 POSIX。因此,该-pedantic标志旨在不允许您做您想做的事情。我刚刚检查了系统上的头文件和编译器配置,如果您使用gcc -std=c99 -pedantic.

你确定你真的要使用那个标志吗?

要使用标准 C 创建一个临时文件,tmpfile那么mmap您需要使用普通freadfwrite.

于 2014-09-10T08:42:25.300 回答
0

通过sort-bed,这是一种fileName使用临时文件名填充指针path并返回的方法FILE*

FILE *
createTmpFile(char const* path, char** fileName)
{
  FILE* fp;
  int fd;
  char* tmpl;

  if (path == NULL)
      {
          fileName = NULL;
          return tmpfile();
      }

  tmpl = (char*)malloc(1 + strlen(path) + L_tmpnam);
  strcpy(tmpl, path);
  strcpy(tmpl+strlen(path), "/sb.XXXXXX");
  fd = mkstemp(tmpl);
  if(fd == -1)
      {
          fprintf(stderr, "unable to create temp file!\n");
          return NULL;
      }
  fp = fdopen(fd, "wb+");
  *fileName = (char*)malloc(strlen(tmpl) + 1);
  strcpy(*fileName, tmpl);
  free(tmpl);
  return fp;
}
于 2014-09-10T08:55:46.383 回答