簡體   English   中英

Ansi C和臨時文件

[英]Ansi C and Temporary Files

我需要來自臨時文件的整數文件描述符,以便在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
} 

與運行,要么與鐺或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的內容?

您無法實現自己想要的。

-pedantic的文檔說:

發出嚴格的ISO C和ISO C ++要求的所有警告; 拒絕所有使用禁止擴展名的程序,以及一些不遵循ISO C和ISO C ++的程序。 對於ISO C,遵循使用的任何-std選項指定的ISO C標准版本。

整數文件描述符不是C標准的一部分。 他們來自POSIX。 另外,C標准中沒有mmap ,它也來自POSIX。 因此, -pedantic標志被設計為不允許您執行您想做的事情。 我只是檢查了系統上的頭文件和編譯器配置,如果使用gcc -std=c99 -pedantic編譯,則它們顯式排除(很多,但不是全部)POSIX函數。

您確定要使用該標志嗎?

要使用標准C創建一個臨時文件,請使用tmpfile而不是mmap ,而需要使用普通的freadfwrite讀寫該文件。

通過sort-bed ,這是在path內使用臨時文件名填充fileName指針並返回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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM