fopencookie(3) - wariua/manpages-ko GitHub Wiki
fopencookie - ๋ง์ถคํ ์คํธ๋ฆผ ์ด๊ธฐ
#define _GNU_SOURCE /* feature_test_macros(7) ์ฐธ๊ณ */
#include <stdio.h>
FILE *fopencookie(void *cookie, const char *mode,
cookie_io_functions_t io_funcs);
fopencookie()
ํจ์๋ฅผ ํตํด ํ๋ก๊ทธ๋๋จธ๊ฐ ํ์ค I/O ์คํธ๋ฆผ์ ๋ง์ถคํ ๊ตฌํ์ ๋ง๋ค ์ ์๋ค. ๊ทธ ๊ตฌํ์์๋ ์ํ๋ ์์น์ ์คํธ๋ฆผ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ ์ ์๋ค. ์๋ฅผ ๋ค์ด ๋ฉ๋ชจ๋ฆฌ ๋ด ๋ฒํผ์ ์ ์ฅ๋ ๋ฐ์ดํฐ์ ๋ํด ์คํธ๋ฆผ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํ๋ fmemopen(3)์ ๊ตฌํํ๋ ๋ฐ fopencookie()
๊ฐ ์ฐ์ธ๋ค.
๋ง์ถคํ ์คํธ๋ฆผ์ ๋ง๋ค๋ ค๋ฉด ํ๋ก๊ทธ๋๋จธ๊ฐ ๋ค์์ ํด ์ฃผ์ด์ผ ํ๋ค.
-
์คํธ๋ฆผ์ I/O๋ฅผ ์ํํ ๋ ํ์ค I/O ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ๋ด๋ถ์ ์ผ๋ก ์ฐ๋ ๋ค ๊ฐ์ง "ํ " ํจ์๋ฅผ ๊ตฌํํด์ผ ํ๋ค.
-
"์ฟ ํค" ์๋ฃํ์ ์ ์ํ๋ค. ์์ ์ธ๊ธํ ํ ํจ์๋ค์์ ์ฌ์ฉํ๋ ์ ๋ณด(๊ฐ๋ น ๋ฐ์ดํฐ๋ฅผ ์ด๋์ ์ ์ฅํ๋์ง)๋ฅผ ๋ด๋ ์๋ฃ ๊ตฌ์กฐ์ด๋ค. ํ์ค I/O ํจํค์ง๋ ์ด ์ฟ ํค์ ๋ด์ฉ์ ๋ํด ์๋ฌด๊ฒ๋ ์์ง ๋ชปํ๋ฉฐ (๊ทธ๋์
fopencookie()
๋ก ์ ๋ฌํ ๋void *
ํ์ ) ํ ํจ์ ํธ์ถ ์ ๊ธฐ๊ณ์ ์ผ๋ก ์ฟ ํค๋ฅผ ์ฒซ ๋ฒ์งธ ์ธ์๋ก ์ ๊ณตํ๊ธฐ๋ง ํ๋ค. -
fopencookie()
๋ฅผ ํธ์ถํด ์ ์คํธ๋ฆผ์ ์ด๊ณ ์คํธ๋ฆผ์ ์ฟ ํค์ ํ ํจ์๋ฅผ ์ฐ๊ณํ๋ค.
fopencookie()
ํจ์๋ fopen(3)๊ณผ ๋น์ทํ ์ญํ ์ ํ๋ค. ์ฆ ์ ์คํธ๋ฆผ์ ์ด๊ณ ๊ทธ ์คํธ๋ฆผ ์กฐ์ ์ ์ฌ์ฉํ FILE
๊ฐ์ฒด์ ๋ํ ํฌ์ธํฐ๋ฅผ ๋ฐํํ๋ค.
cookie
์ธ์๋ ํธ์ถ์์ ์ฟ ํค ์๋ฃ ๊ตฌ์กฐ์ ๋ํ ํฌ์ธํฐ์ด๋ฉฐ ์ ์คํธ๋ฆผ์ ์ฐ๊ณ๋๋ค. ํ์ค I/O ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ์๋ ๊ธฐ์ ํ๋ ํ
ํจ์๋ค์ ํธ์ถํ ๋ ์ด ํฌ์ธํฐ๋ฅผ ์ฒซ ๋ฒ์งธ ์ธ์๋ก ์ ๊ณตํ๋ค.
mode
์ธ์๋ fopen(3)์์์ ๊ฐ์ ์ญํ ์ ํ๋ค. ์ง์ํ๋ ๋ชจ๋๋ r
, w
, a
, r+
, w+
, a+
์ด๋ค. ์์ธํ ๋ด์ฉ์ fopen(3)์ ๋ณด๋ผ.
io_funcs
์ธ์๋ ์คํธ๋ฆผ ๊ตฌํ์ ์ํด ํ๋ก๊ทธ๋๋จธ๊ฐ ์ ์ํ ํ
ํจ์๋ค์ ๊ฐ๋ฆฌํค๋ ํ๋ ๋ค ๊ฐ๊ฐ ๋ด๊ธด ๊ตฌ์กฐ์ฒด์ด๋ค. ์ด ๊ตฌ์กฐ์ฒด๋ ๋ค์๊ณผ ๊ฐ์ด ์ ์๋ผ ์๋ค.
typedef struct {
cookie_read_function_t *read;
cookie_write_function_t *write;
cookie_seek_function_t *seek;
cookie_close_function_t *close;
} cookie_io_functions_t;
๋ค ํ๋๋ ๋ค์๊ณผ ๊ฐ๋ค.
cookie_read_function_t *read
-
์ด ํจ์๋ ์คํธ๋ฆผ์ ์ฝ๊ธฐ ๋์์ ๊ตฌํํ๋ค. ํธ์ถ ์ ์ธ์ ์ธ ๊ฐ๋ฅผ ๋ฐ๋๋ค.
ssize_t read(void *cookie, char *buf, size_t size);
buf
์ธ์์size
์ธ์๋ ๊ฐ๊ฐ ์ ๋ ฅ ๋ฐ์ดํฐ๋ฅผ ๋ฃ์ ์ ์๋ ๋ฒํผ์ ๊ทธ ๋ฒํผ์ ํฌ๊ธฐ์ด๋ค. ํจ์ ๊ฒฐ๊ณผ๋กread
ํจ์๋buf
๋ก ๋ณต์ฌํ ๋ฐ์ดํธ ์๋ฅผ, ๋๋ ํ์ผ ๋์ด๋ฉด 0์, ๋๋ ์ค๋ฅ ์ -1์ ๋ฐํํด์ผ ํ๋ค.read
ํจ์๋ ์คํธ๋ฆผ ์คํ์ ์ ์ ์ ํ ๊ฐฑ์ ํด์ผ ํ๋ค.*read
๊ฐ ๋ ํฌ์ธํฐ์ด๋ฉด ๋ง์ถคํ ์คํธ๋ฆผ ์ฝ๊ธฐ๊ฐ ํญ์ ํ์ผ ๋์ ๋ฐํํ๋ค. cookie_write_function_t *write
-
์ด ํจ์๋ ์คํธ๋ฆผ์ ์ฐ๊ธฐ ๋์์ ๊ตฌํํ๋ค. ํธ์ถ ์ ์ธ์ ์ธ ๊ฐ๋ฅผ ๋ฐ๋๋ค.
ssize_t write(void *cookie, const char *buf, size_t size);
buf
์ธ์์size
์ธ์๋ ๊ฐ๊ฐ ์คํธ๋ฆผ์ผ๋ก ์ถ๋ ฅํ ๋ฐ์ดํฐ๊ฐ ์๋ ๋ฒํผ์ ๊ทธ ๋ฒํผ์ ํฌ๊ธฐ์ด๋ค. ํจ์ ๊ฒฐ๊ณผ๋กwrite
ํจ์๋buf
๋ก๋ถํฐ ๋ณต์ฌํ ๋ฐ์ดํธ ์๋ฅผ, ๋๋ ์ค๋ฅ ์ 0์ ๋ฐํํด์ผ ํ๋ค. (ํจ์๊ฐ ์์ ๊ฐ์ ๋ฐํํด์ ์ ๋๋ค.)write
ํจ์๋ ์คํธ๋ฆผ ์คํ์ ์ ์ ์ ํ ๊ฐฑ์ ํด์ผ ํ๋ค.*write
๊ฐ ๋ ํฌ์ธํฐ์ด๋ฉด ์คํธ๋ฆผ์ ๋ํ ์ถ๋ ฅ์ด ๋ฒ๋ ค์ง๋ค. cookie_seek_function_t *seek
-
์ด ํจ์๋ ์คํธ๋ฆผ์ ํ์ ๋์์ ๊ตฌํํ๋ค. ํธ์ถ ์ ์ธ์ ์ธ ๊ฐ๋ฅผ ๋ฐ๋๋ค.
int seek(void *cookie, off64_t *offset, int whence);
*offset
์ธ์๋ ์ ํ์ผ ์คํ์ ์ ๋ํ๋ด๋๋ฐ,whence
์ ๋ค์ ์ค ์ด๋ ๊ฐ์ด ์๋๋์ ๋ฐ๋ผ ๋ฌ๋ผ์ง๋ค.SEEK_SET
- ์คํธ๋ฆผ ์คํ์
์ ์คํธ๋ฆผ ์์์ ๊ธฐ์ค
*offset
๋ฐ์ดํธ๋ก ์ค์ ํด์ผ ํ๋ค. SEEK_CUR
- ํ์ฌ ์คํธ๋ฆผ ์คํ์
์
*offset
์ ๋ํด์ผ ํ๋ค. SEEK_END
- ์คํธ๋ฆผ ์คํ์
์ ์คํธ๋ฆผ ํฌ๊ธฐ ๋ํ๊ธฐ
*offset
์ผ๋ก ์ค์ ํด์ผ ํ๋ค.
๋ฐํ ์ ์
seek
ํจ์๋ ์ ์คํธ๋ฆผ ์คํ์ ์ ๋ํ๋ด๋๋ก*offset
์ ๊ฐฑ์ ํด์ผ ํ๋ค.ํจ์ ๊ฒฐ๊ณผ๋ก
seek
ํจ์๋ ์ฑ๊ณต ์ 0์ ๋ฐํํ๊ณ ์ค๋ฅ ์ -1์ ๋ฐํํด์ผ ํ๋ค.*seek
์ด ๋ ํฌ์ธํฐ์ด๋ฉด ์คํธ๋ฆผ์์ ํ์ ๋์์ ์ํํ๋ ๊ฒ ๋ถ๊ฐ๋ฅํ๋ค. cookie_close_function_t *close
-
์ด ํจ์๋ ์คํธ๋ฆผ์ ๋ซ๋๋ค. ์คํธ๋ฆผ์ ์ํด ํ ๋นํ๋ ๋ฒํผ๋ฅผ ํด์ ํ๋ ๊ฒ ๊ฐ์ ์ผ์ ํ ํจ์์์ ํ ์ ์๋ค. ํธ์ถ ์ ์ธ์ ํ ๊ฐ๋ฅผ ๋ฐ๋๋ค.
int close(void *cookie);
cookie
์ธ์๋ ํ๋ก๊ทธ๋๋จธ๊ฐfopencookie()
ํธ์ถ ์ ์ ๊ณตํ๋ ์ฟ ํค์ด๋ค.ํจ์ ๊ฒฐ๊ณผ๋ก
close
ํจ์๋ ์ฑ๊ณต ์ 0์ ๋ฐํํ๊ณ ์ค๋ฅ ์EOF
๋ฅผ ๋ฐํํด์ผ ํ๋ค.*close
๊ฐ NULL์ด๋ฉด ์คํธ๋ฆผ์ ๋ซ์ ๋ ๋ณ๋ค๋ฅธ ๋์์ ์ํํ์ง ์๋๋ค.
์ฑ๊ณต ์ fopencookie()
๋ ์ ์คํธ๋ฆผ์ ๋ํ ํฌ์ธํฐ๋ฅผ ๋ฐํํ๋ค. ์ค๋ฅ ์ NULL์ ๋ฐํํ๋ค.
์ด ์ ์์ ์ฌ์ฉํ๋ ์ฉ์ด๋ค์ ๋ํ ์ค๋ช ์ attributes(7)๋ฅผ ๋ณด๋ผ.
์ธํฐํ์ด์ค | ์์ฑ | ๊ฐ |
---|---|---|
fopencookie() |
์ค๋ ๋ ์์ ์ฑ | MT-Safe |
์ด ํจ์๋ ๋นํ์ค GNU ํ์ฅ์ด๋ค.
์๋ ํ๋ก๊ทธ๋จ์์๋ fmemopen(3)์ ํตํด ์ฌ์ฉ ๊ฐ๋ฅํ ๊ฒ๊ณผ ๊ธฐ๋ฅ์ด ๋น์ทํ (ํ์ง๋ง ๋์ผํ์ง๋ ์์) ๋ง์ถคํ ์คํธ๋ฆผ์ ๊ตฌํํ๋ค. ์ฆ ๋ฉ๋ชจ๋ฆฌ ๋ฒํผ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ ์คํธ๋ฆผ์ ๊ตฌํํ๋ค. ํ๋ก๊ทธ๋จ์์ ๋ช ๋ นํ ์ธ์๋ค์ ์คํธ๋ฆผ์ผ๋ก ์จ๋ฃ์ ๋ค์ ์คํธ๋ฆผ์ ํ์ํ๋ฉฐ ๋ค์ฏ ๊ธ์๋ง๋ค ๋ ๊ธ์์ฉ์ ์ฝ์ด์ ํ์ค ์ถ๋ ฅ์ ์ด๋ค. ๋ค์ ์ ธ ์ธ์ ์ด ํ๋ก๊ทธ๋จ ์ฌ์ฉ ๋ฐฉ์์ ๋ณด์ฌ ์ค๋ค.
$ ./a.out 'hello world'
/he/
/ w/
/d/
Reached end of file
์ฐธ๊ณ ๋ก ์๋ ํ๋ก๊ทธ๋จ์ ๋ ๋ฒ์ฉ์ ์ผ๋ก ๋ง๋ค๋ ค๋ฉด ๋ค์ํ ์ค๋ฅ ์ํฉ๋ค(๊ฐ๋ น ์คํธ๋ฆผ ์ฌ๋ ๋ฐ ์ฌ์ฉํ ์ฟ ํค๋ก ๋ค๋ฅธ ์คํธ๋ฆผ ์ด๊ธฐ, ์ด๋ฏธ ๋ซํ ์คํธ๋ฆผ ๋ซ๊ธฐ)์ ๊ฒฌ๊ณ ํ๊ฒ ๋ค๋ฃจ๋๋ก ๊ฐ์ ํ ์ ์์ ๊ฒ์ด๋ค.
#define _GNU_SOURCE
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define INIT_BUF_SIZE 4
struct memfile_cookie {
char *buf; /* ๋์ ํฌ๊ธฐ์ ๋ฐ์ดํฐ ๋ฒํผ */
size_t allocated; /* buf์ ํฌ๊ธฐ */
size_t endpos; /* buf ๋ด์ ๋ฌธ์ ๊ฐ์ */
off_t offset; /* buf ๋ด์ ํ์ฌ ํ์ผ ์คํ์
*/
};
ssize_t
memfile_write(void *c, const char *buf, size_t size)
{
char *new_buff;
struct memfile_cookie *cookie = c;
/* ๋ฒํผ ๋ถ์กฑ? ์ถฉ๋ถํ ์ปค์ง ๋๊น์ง ๋ ๋ฐฐ์ฉ ํค์ฐ๊ธฐ */
while (size + cookie->offset > cookie->allocated) {
new_buff = realloc(cookie->buf, cookie->allocated * 2);
if (new_buff == NULL) {
return -1;
} else {
cookie->allocated *= 2;
cookie->buf = new_buff;
}
}
memcpy(cookie->buf + cookie->offset, buf, size);
cookie->offset += size;
if (cookie->offset > cookie->endpos)
cookie->endpos = cookie->offset;
return size;
}
ssize_t
memfile_read(void *c, char *buf, size_t size)
{
ssize_t xbytes;
struct memfile_cookie *cookie = c;
/* ์์ฒญ ๋ฐ์ดํธ์ ๊ฐ์ฉ ๋ฐ์ดํธ ์ค ์์ ์ชฝ ๊ฐ์ ธ์ค๊ธฐ */
xbytes = size;
if (cookie->offset + size > cookie->endpos)
xbytes = cookie->endpos - cookie->offset;
if (xbytes < 0) /* offset์ด endpos๋ฅผ ์ง๋ฌ์ ์ ์์ */
xbytes = 0;
memcpy(buf, cookie->buf + cookie->offset, xbytes);
cookie->offset += xbytes;
return xbytes;
}
int
memfile_seek(void *c, off64_t *offset, int whence)
{
off64_t new_offset;
struct memfile_cookie *cookie = c;
if (whence == SEEK_SET)
new_offset = *offset;
else if (whence == SEEK_END)
new_offset = cookie->endpos + *offset;
else if (whence == SEEK_CUR)
new_offset = cookie->offset + *offset;
else
return -1;
if (new_offset < 0)
return -1;
cookie->offset = new_offset;
*offset = new_offset;
return 0;
}
int
memfile_close(void *c)
{
struct memfile_cookie *cookie = c;
free(cookie->buf);
cookie->allocated = 0;
cookie->buf = NULL;
return 0;
}
int
main(int argc, char *argv[])
{
cookie_io_functions_t memfile_func = {
.read = memfile_read,
.write = memfile_write,
.seek = memfile_seek,
.close = memfile_close
};
FILE *stream;
struct memfile_cookie mycookie;
ssize_t nread;
long p;
int j;
char buf[1000];
/* ์ฟ ํค ์ค๋นํ๊ณ fopencookie() ํธ์ถ */
mycookie.buf = malloc(INIT_BUF_SIZE);
if (mycookie.buf == NULL) {
perror("malloc");
exit(EXIT_FAILURE);
}
mycookie.allocated = INIT_BUF_SIZE;
mycookie.offset = 0;
mycookie.endpos = 0;
stream = fopencookie(&mycookie,"w+", memfile_func);
if (stream == NULL) {
perror("fopencookie");
exit(EXIT_FAILURE);
}
/* ๋ช
๋ นํ ์ธ์๋ฅผ ์ฐ๋ฆฌ ํ์ผ๋ก ๊ธฐ๋ก */
for (j = 1; j < argc; j++)
if (fputs(argv[j], stream) == EOF) {
perror("fputs");
exit(EXIT_FAILURE);
}
/* EOF ์ ๊น์ง ๋ค์ฏ ๋ฐ์ดํธ๋ง๋ค ๋ ๋ฐ์ดํธ์ฉ ์ฝ๊ธฐ */
for (p = 0; ; p += 5) {
if (fseek(stream, p, SEEK_SET) == -1) {
perror("fseek");
exit(EXIT_FAILURE);
}
nread = fread(buf, 1, 2, stream);
if (nread == -1) {
perror("fread");
exit(EXIT_FAILURE);
}
if (nread == 0) {
printf("Reached end of file\n");
break;
}
printf("/%.*s/\n", nread, buf);
}
exit(EXIT_SUCCESS);
}
fclose(3), fmemopen(3), fopen(3), fseek(3)
2019-03-06