Manpages

名 前

fmemopen, open_memstream, open_wmemstream − メ モ リ ー を ス ト リ ー ム と し て オ ー プ ン す る

書 式

#include <stdio.h>

FILE *fmemopen(void *buf, size_t size, const char *mode);

FILE *open_memstream(char **ptr, size_t *sizeloc);

#include <wchar.h>

FILE *open_wmemstream(wchar_t **ptr, size_t *sizeloc);

glibc 向 け の 機 能 検 査 マ ク ロ の 要 件 (feature_test_macros(7) 参 照 ):

fmemopen(), open_memstream(), open_wmemstream():

glibc 2.10 以 降 :

_XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L

glibc 2.10 よ り 前 :

_GNU_SOURCE

説 明

fmemopen() 関 数 は 、 ス ト リ ー ム を オ ー プ ン し 、 そ の ス ト リ ー ム に mode で 指 定 さ れ た ア ク セ ス 許 可 を 設 定 す る 。 そ の ス ト リ ー ム を 通 じ て 、 buf で 指 定 さ れ た 文 字 列 や メ モ リ ー バ ッ フ ァ ー へ の 読 み 書 き が で き る 。 こ の バ ッ フ ァ ー は 少 な く と も size バ イ ト の 長 さ で な け れ ば な ら な い 。 引 き 数 modefopen(3) の 場 合 と 同 じ で あ る 。 mode で 追 記 モ ー ド (append mode) が 指 定 さ れ た 場 合 、 フ ァ イ ル 位 置 の 初 期 値 は バ ッ フ ァ ー 中 の 最 初 の ヌ ル バ イ ト ('\0') の 位 置 に 設 定 さ れ る 。 そ れ 以 外 の 場 合 は 、 フ ァ イ ル 位 置 の 初 期 値 は バ ッ フ ァ ー の 先 頭 に な る 。 glibc 2.9 以 降 で は 、 文 字 'b' を mode の 二 番 目 の 文 字 と し て 指 定 す る こ と が で き る 。 こ の 文 字 は 「 バ イ ナ リ 」 モ ー ド を 指 定 す る も の で あ る 。 こ の モ ー ド で は 、 書 き 込 み 時 に 文 字 列 終 端 の ヌ ル バ イ ト が 黙 っ て 追 加 さ れ る こ と は な い 。 ま た 、 fseek(3) SEEK_END は 、 文 字 列 の 長 さ か ら の 相 対 値 で は な く 、 バ ッ フ ァ ー の 末 尾 (size で 指 定 し た 値 ) か ら の 相 対 値 と な る 。 書 き 込 み 用 に オ ー プ ン さ れ た ス ト リ ー ム を フ ラ ッ シ ュ (fflush(3)) や ク ロ ー ズ (fclose(3)) し た 時 に 、 (バ ッ フ ァ ー に 空 き が あ れ ば ) ヌ ル バ イ ト が バ ッ フ ァ ー の 末 尾 に 書 き 込 ま れ る 。 こ の よ う に す る た め に は 、 呼 び 出 し 元 は バ ッ フ ァ ー に 1バ イ ト 余 裕 を 作 る (size に こ の 1バ イ ト を 含 め た 値 を 指 定 す る ) 必 要 が あ る 。 バ ッ フ ァ ー に size バ イ ト よ り た く さ ん 書 き 込 も う と し た 場 合 に は 、 エ ラ ー と な る 。 (デ フ ォ ル ト で は 、 こ の よ う な エ ラ ー が 見 え る の は stdio バ ッ フ ァ ー が フ ラ ッ シ ュ さ れ た 時 だ け で あ る 。 以 下 の 呼 び 出 し を 使 っ て バ ッ フ ァ ー リ ン グ を 無 効 に す る 方 法 は 、 出 力 操 作 を 行 っ た 時 点 で エ ラ ー を 検 出 す る の に 役 立 つ 。

setbuf(stdream, NULL); 別 の 方 法 と し て は 、 以 下 の よ う に 、 呼 び 出 し 側 が 明 示 的 に stdio ス ト リ ー ム バ ッ フ ァ ー と し て buf を 指 定 し 、 バ ッ フ ァ ー の 指 定 時 に バ ッ フ ァ ー の サ イ ズ を stdio に 教 え る 方 法 が あ る 。

setbuffer(stream, buf, size); 読 み 出 し 用 に オ ー プ ン さ れ た ス ト リ ー ム で は 、 バ ッ フ ァ ー 内 に ヌ ル バ イ ト ('\0') が あ っ て も 読 み 出 し 操 作 が フ ァ イ ル 末 尾 (end−of−file) を 返 す こ と は な い 。 バ ッ フ ァ ー か ら の 読 み 出 し で フ ァ イ ル 末 尾 が 返 る の は 、 フ ァ イ ル ポ イ ン タ ー が バ ッ フ ァ ー の 先 頭 か ら size バ イ ト を 越 え て 先 に 進 も う と し た 場 合 だ け で あ る 。

buf に NULL が 指 定 さ れ た 場 合 、 fmemopen() は 動 的 に size バ イ ト の 長 さ の バ ッ フ ァ ー を 確 保 す る 。 こ の 方 法 は 、 一 時 バ ッ フ ァ ー に デ ー タ の 書 き 込 み を 行 っ て か ら 、 そ の 内 容 を 再 度 読 み 出 す よ う な ア プ リ ケ ー シ ョ ン で 有 用 で あ る 。 こ の バ ッ フ ァ ー は ス ト リ ー ム が ク ロ ー ズ さ れ る と き に 自 動 的 に 解 放 さ れ る 。 呼 び 出 し 元 か ら は こ の 関 数 が 割 り 当 て た 一 時 バ ッ フ ァ ー へ の ポ イ ン タ ー 値 を 知 る 方 法 は 存 在 し な い 点 に 注 意 (下 記 の open_memstream() も 参 照 )。

open_memstream() 関 数 は 、 バ ッ フ ァ ー へ の 書 き 込 み 用 に ス ト リ ー ム を オ ー プ ン す る 。 バ ッ フ ァ ー は (malloc(3) を 使 っ て ) 動 的 に 割 り 当 て ら れ 、 必 要 に 応 じ て 自 動 的 に 伸 長 す る 。 ス ト リ ー ム を ク ロ ー ズ し た 後 で 、 呼 び 出 し 元 は こ の バ ッ フ ァ ー を free(3) す べ き で あ る 。 こ の ス ト リ ー ム が ク ロ ー ズ (fclose(3)) さ れ た り フ ラ ッ シ ュ (fflush(3)) さ れ た 時 に 、 ptrsizeloc の 値 は そ れ ぞ れ バ ッ フ ァ ー へ の ポ イ ン タ ー と そ の サ イ ズ に 更 新 さ れ る 。 こ れ ら の 値 は 、 呼 び 出 し 元 が そ の ス ト リ ー ム に 新 た な 書 き 込 み を 行 わ な い 場 合 に 限 り 有 効 で あ る 。 ス ト リ ー ム に 書 き 込 み を 行 っ た 際 に は 、 こ れ ら の 変 数 を 参 照 す る 前 に ス ト リ ー ム を 再 度 フ ラ ッ シ ュ し な け れ ば な ら な い 。 バ ッ フ ァ ー 末 尾 の ヌ ル バ イ ト は 保 持 さ れ る 。 こ の ヌ ル バ イ ト は sizeloc に 格 納 さ れ る サ イ ズ に は 「 含 ま れ な い 」 。 ス ト リ ー ム の フ ァ イ ル 位 置 は fseek(3)fseeko(3) で 変 更 で き る 。 す で に デ ー タ が 書 き 込 ま れ た 領 域 の 末 尾 よ り 先 に フ ァ イ ル 位 置 を 動 か す と 、 そ の 間 の 領 域 は 0 で 埋 め ら れ る 。

open_wmemstream() は open_memstream() と 同 様 だ が 、 バ イ ト で は な く ワ イ ド 文 字 に 対 し て 操 作 を 行 う 点 が 異 な る 。

返 り 値

成 功 し て 終 了 し た 場 合 に は 、 fmemopen(), open_memstream(), open_wmemstream() は FILE ポ イ ン タ ー を 返 す 。 失 敗 し た 場 合 は 、 NULL を 返 し 、 errno に エ ラ ー を 示 す 値 を セ ッ ト す る 。

バ ー ジ ョ ン

fmemopen() と open_memstream() は glibc 1.0.x で す で に 利 用 可 能 で あ っ た 。 open_wmemstream() は glibc 2.4 以 降 で 利 用 可 能 で あ る 。

準 拠

POSIX.1−2008. こ れ ら の 関 数 は POSIX.1−2001 で は 規 定 れ て い な い が 、 Linux 以 外 の シ ス テ ム で 広 く 利 用 可 能 で あ る 。

POSIX.1−2008 で は mode の 'b' は 無 視 さ れ る べ き だ と 規 定 さ れ て い る 。 一 方 、 Technical Corrigendum (正 誤 表 ) 1 で は 、 mode の 'b' が 指 定 さ れ た 場 合 の 扱 い は 実 装 依 存 で あ る こ と を 許 容 す る よ う に 標 準 規 格 が 修 正 さ れ て お り 、 glibc の 'b' の 扱 い は 許 さ れ て い る 。

注 意

こ れ ら の 関 数 が 返 す フ ァ イ ル ス ト リ ー ム に 対 応 す る フ ァ イ ル デ ィ ス ク リ プ タ ー は な い (つ ま り 、 返 さ れ た ス ト リ ー ム に 対 し て fileno(3) を 呼 び 出 す と エ ラ ー が 返 る こ と に な る )。

バ グ

バ ー ジ ョ ン 2.7 よ り 前 の glibc で は 、 open_memstream() で 作 成 さ れ た ス ト リ ー ム の 末 尾 よ り 先 に フ ァ イ ル 位 置 を 動 か し て も 、 バ ッ フ ァ ー が 伸 長 さ れ ず 、 fseek(3) が 失 敗 し −1 が 返 る 。

size に 0 が 指 定 さ れ た 場 合 、 fmemopen() は エ ラ ー EINVAL で 失 敗 す る 。 こ の 場 合 に は ス ト リ ー ム の 作 成 に 成 功 し て 、 最 初 の 読 み 出 し を 行 っ た 際 に EOF (end of file) が 返 さ れ る 方 が 、 ス ト リ ー ム の 扱 い の 一 貫 性 が 増 す だ ろ う 。 ま た 、 POSIX.1−2008 で は こ の 場 合 の エ ラ ー は 規 定 さ れ て い な い 。

fmemopen() に 追 記 モ ー ド ("a" や "a+") を 指 定 す る と 、 フ ァ イ ル 位 置 の 初 期 値 は 最 初 の ヌ ル バ イ ト に 設 定 さ れ る が 、 (フ ァ イ ル オ フ セ ッ ト を ス ト リ ー ム の 末 尾 以 外 の 位 置 に 再 設 定 し た 場 合 )そ れ 以 降 の 書 き 込 み で は ス ト リ ー ム の 末 尾 へ の 追 記 が 行 わ れ る 訳 で は な い 。

fmemopen() の mode 引 き 数 に 追 記 モ ー ド ("a" や "a+") を 指 定 し 、 size 引 き 数 で 指 定 し た 範 囲 の buf 内 に ヌ ル バ イ ト が な い 場 合 、 POSIX.1−2008 で は 、 フ ァ イ ル 位 置 の 初 期 値 は バ ッ フ ァ ー の 末 尾 の 直 後 の バ イ ト に 設 定 す べ き と さ れ て い る 。 し か し 、 glibc の fmemopen() で は こ の 場 合 フ ァ イ ル 位 置 は −1 に 設 定 さ れ る 。

fmemopen() で バ イ ナ リ モ ー ド を 指 定 す る に は 、 'b' は mode2 文 字 目 で な け れ ば な ら な い 。 例 え ば 、 "wb+" は 意 図 通 り の 効 果 に な る が 、 "w+b" は そ う で は な い 。 こ れ は fopen(3)mode の 扱 い と は 異 な る 。

glibc 2.9 で の fmemopen() の 「 バ イ ナ リ 」 モ ー ド の 追 加 は 、 ABI (Application Binary Interface) が 黙 っ て 変 更 さ れ た 。 そ れ 以 前 の fmemopen() で は mode 内 の 'b' は 無 視 さ れ て い た 。

こ の プ ロ グ ラ ム は fmemopen() を 使 っ て 出 力 バ ッ フ ァ ー を オ ー プ ン し 、 open_memstream() を 使 っ て 動 的 に サ イ ズ が 変 化 す る 出 力 バ ッ フ ァ ー を オ ー プ ン し て い る 。 (プ ロ グ ラ ム の 第 一 コ マ ン ド ラ イ ン 引 き 数 か ら 取 っ た ) 入 力 文 字 列 を ス キ ャ ン し て 整 数 を 読 み 込 み 、 こ れ ら の 整 数 の 二 乗 を 出 力 バ ッ フ ァ ー に 書 き 出 す 。 こ の プ ロ グ ラ ム の 実 行 例 は 以 下 の よ う に な る 。

$ ./a.out '1 23 43'
size=11; ptr=1 529 1849 プ ロ グ ラ ム の ソ ー ス

#define _GNU_SOURCE
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#define handle_error(msg) \
do { perror(msg); exit(EXIT_FAILURE); } while (0)

int
main(int argc, char *argv[])
{
FILE *out, *in;
int v, s;
size_t size;
char *ptr;

if (argc != 2) {
fprintf(stderr, "Usage: %s <file>\n", argv[0]);
exit(EXIT_FAILURE); }

in = fmemopen(argv[1], strlen(argv[1]), "r");
if (in == NULL)
handle_error("fmemopen");

out = open_memstream(&ptr, &size);
if (out == NULL)
handle_error("open_memstream");

for (;;) {
s = fscanf(in, "%d", &v);
if (s <= 0)
break;

s = fprintf(out, "%d ", v * v);
if (s == −1)
handle_error("fprintf"); }
fclose(in);
fclose(out);
printf("size=%zu; ptr=%s\n", size, ptr);
free(ptr);
exit(EXIT_SUCCESS); }

関 連 項 目

fopen(3), fopencookie(3)

こ の 文 書 に つ い て

こ の man ペ ー ジ は Linux man−pages プ ロ ジ ェ ク ト の リ リ ー ス 3.79 の 一 部 で あ る 。 プ ロ ジ ェ ク ト の 説 明 と バ グ 報 告 に 関 す る 情 報 は http://www.kernel.org/doc/man−pages/ に 書 か れ て い る 。