[英]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
,而需要使用普通的fread
和fwrite
讀寫該文件。
通過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.