|
|
||
ファイルポインタから、ファイル記述子を求める方法を学習。
書籍ではRedhatの例が以下のように書かれていた。
FILE *fp; fp = fopen("hoge.dat", "r"); // ファイルポインタからファイル記述子を求める方法その1。(REDHATの場合) fd = fp->_fileno // ファイルポインタからファイル記述子を求める方法その2。(REDHATの場合) fd = fileno(fp);
FreeBSDの場合、どうなるのか調べてみる。
fpからファイル記述子を求める場合、FreeBSDの場合でもfileno関数を使うので、このソースをあたってみる。
まず、fileno関数のmanを見ると、Standard C Libraryとあるので、/usr/src/lib/libcあたりにソースがあることが推測できます。
black:~$ find /usr/src/lib/libc -type f -name fileno.c /usr/src/lib/libc/stdio/fileno.c black:~$ cat /usr/src/lib/libc/stdio/fileno.c ・・・省略・・・ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)fileno.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include <sys/cdefs.h> __FBSDID("$FreeBSD: src/lib/libc/stdio/fileno.c,v 1.10 2004/03/17 01:43:07 tjr Exp $"); #include "namespace.h" #include <stdio.h> #include "un-namespace.h" #include "libc_private.h" #undef fileno int fileno(FILE *fp) { int fd; FLOCKFILE(fp); fd = __sfileno(fp); FUNLOCKFILE(fp); return (fd); }
fpを__sfilenoに渡してfdを得ているようです。__sfilenoはcファイルでは定義されてないようなのでマクロかもしれません。(関数名の先頭にアンダースコアをつけるとマクロだよという意味なのかも。。)
とりあえず、ヘッダを調べてみます。
black:/usr$ sudo find . -type f -name \*h -exec grep -l __sfileno {} \; ./include/stdio.h ./local/lib/perl5/site_perl/5.8.6/mach/stdio.ph ./src/include/stdio.h
stdio.hというファイルがそれっぽいですが、include配下のものとsrc/include配下のものがあります。
どちらを見ればよいのかわかりませんが、内容は同じようですのでここでは気にしません。(ToDo:何故、同じファイルが違う場所においてあるのか調べてみる)
とりあえず、grepしてみます。
black:/usr$ grep __sfileno ./src/include/stdio.h #define __sfileno(p) ((p)->_file) #define fileno(p) (!__isthreaded ? __sfileno(p) : (fileno)(p)) #define fileno_unlocked(p) __sfileno(p)
やはり、defineだったようです。
パラメタで渡しているpポインタは、FILE構造体となります。
FILE構造体はstdio.hで以下のように定義されていました。
typedef struct __sFILE { unsigned char *_p; /* current position in (some) buffer */ int _r; /* read space left for getc() */ int _w; /* write space left for putc() */ short _flags; /* flags, below; this FILE is free if 0 */ short _file; /* fileno, if Unix descriptor, else -1 */ struct __sbuf _bf; /* the buffer (at least 1 byte, if !NULL) */ int _lbfsize; /* 0 or -_bf._size, for inline putc */ /* operations */ void *_cookie; /* cookie passed to io functions */ int (*_close)(void *); int (*_read)(void *, char *, int); fpos_t (*_seek)(void *, fpos_t, int); int (*_write)(void *, const char *, int); /* separate buffer for long sequences of ungetc() */ struct __sbuf _ub; /* ungetc buffer */ struct __sFILEX *_extra; /* additions to FILE to not break ABI */ int _ur; /* saved _r when _r is counting ungetc data */ /* tricks to meet minimum requirements even when malloc() fails */ unsigned char _ubuf[3]; /* guarantee an ungetc() buffer */ unsigned char _nbuf[1]; /* guarantee a getc() buffer */ /* separate buffer for fgetln() when line crosses buffer boundary */ struct __sbuf _lb; /* buffer for fgetln() */ /* Unix stdio files get aligned to block boundaries on fseek() */ int _blksize; /* stat.st_blksize (may be != _bf._size) */ fpos_t _offset; /* current lseek offset */ } FILE;
ファイルポインタからファイル記述子を求める場合、RedHatの場合は、fp->_filenoなのに、FreeBSDの場合はfp->_fileという違いがあるようです。
py4s-tnk2008/10/19 01:28resetコマンドでもできる