Chinaunix首页 | 论坛 | 博客
  • 博客访问: 55674
  • 博文数量: 13
  • 博客积分: 850
  • 博客等级: 准尉
  • 技术积分: 220
  • 用 户 组: 普通用户
  • 注册时间: 2007-09-10 16:20
文章存档

2008年(13)

我的朋友
最近访客

分类: C/C++

2008-10-30 21:35:01

标准I/O库.
这个东东一般只要上个C语言的人都学过.比如printf函数.这些东东,大都是建立在一个叫FILE的对象上.
下面我清数下这此函数.(可能还有很多没有!)

int fwide(FILE *fp,int mode);      //流处理是宽字节还是字节的或者无字节的,看下面的_IO_fwide_maybe_incompatible
void setbuf(FILE* fp,char *restrict buf);       //设置文件流是是行缓冲,还是全缓冲,一般是全缓冲,但与具体设备相关就不一定了.
int setvbuf(FILE* fp,char *restrict buf,int mode,size_t size);//同上,但是指出是什么样的缓冲
int fflush(FILE *fp);   //刷新缓冲区

FILE* fopen(const char *restrict pathname,const char *restrict type);     //看下篇
FILE* freopen(const char *restrict pathname,const char * restrict type,FILE *restrict fp);//相当于先关闭,再打开一次
FILE* fdopen(int filedes,const char *type);//根据文件描述符打开文件流

int getc(FILE *fp);     //下面已经有实现宏
int fgetc(FILE *fp);    //功能和getc一样,但是它是个函数,而getc是一个宏
int getchar(void);     //他从stdin里取数据,看下面_IO_stdin宏
//以上三个函数成功都返回下一个字符 

#define _IO_feof_unlocked(__fp) (((__fp)->_flags & _IO_EOF_SEEN) != 0)      //是否文件结束
#define _IO_ferror_unlocked(__fp) (((__fp)->_flags & _IO_ERR_SEEN) != 0)    //判断标志,是否出错
int ferror(FILE *fp);    //判断是否出错 ,具体看下面
int feof(FILE *fp);      //判断是否到文件尾
void clearerr(FILE *fp);  //清除上面两个标志

ungetc(int c,FILE *fp); //倒序取流的字节

int putc(int c,FILE *fp);     //_IO_putc_unlocked
int fputc(int c,FILE *fp);
int putchar(int c);

char* fgets(char *restrict buf,int n,FILE*restrict fp);//看下篇,其实是用_IO_putc_unlocked实现的
char* gets(char *buf);                  //这个函数和上面基本一样,取的设备是stdout,但没有缓冲区大小,可能溢出


//注意这里是结构读写,并不是字节读写.nobj对象个数,size表示一个对象的大小,ptr为缓冲指针
size_t fread(void *restrict ptr,size_t size,size_t nobj,FILE *restrict fp);    //看下篇
size_t fwrite(const void* restrict ptr,size_t size,size_t nobj,FILE *restrict fp);

long ftell(FILE *fp);          //返回流的当前位置,我们现在看到了FILE结构,所以这个很简单吧.
int fseek(FILE *fp,long offset,int whence);   //设置流的当前位置
void rewind(FILE *fp);     //直接设置流到起始位置,无返回值.

off_t ftello(FILE *fp);         //可以看出这两个函数和上面的两个一样,只是long 变成了off_t,实际他功能确实如此
int fseeko(FILE *fp,off_t offset,int whence);

int fgetpos(FILE *restrict fp,fpos_t *restrict pos);  //这两个函数和fseek及ftell,只是他们将位置放到了参数内部
int fsetpos(FILE *fp,const fpos_t *pos);              //并且文件偏移类型也由long -->fpos_t了.


//下面八个格式化输出
int printf(const char *restrict format,...);         //格式化输出到stdout里
int fprintf(FILE *fp,const char *restrict format,...);     //格式化输出到fp
int sprintf(char *restrict buf, const char *restrict format,...);      //格式化输出到字符数组里
int snprintf(char *restrict buf,size_t n,const char* restrict format,...); //格式化输出到指定长度的数组里

int vprintf(const char *restrict format ,va_list arg);           //这四个函数和上面一模一样,只是将va_list arg代替...,
int vfprintf(FILE* restrict fp,const char *restrict format,va_list arg);      //其实实际编译后台也会作此转换的.
int vsprintf(char * restrict buf,const char *restrict format,va_list arg);
int vsnprintf(char * restrict buf,size_t n,const char *restrict format,va_list arg);

//再下面六个格式化输入
int scanf(const char *restrict format,...);      //从stdin里输入,不用说.记得...代表是地址.
int fscanf(FILE *restrict fp,const char *restrict format,...);              //上面一样,stdin变成了fp
int sscanf(const char *restrict buf,const char *restrict format,...);     //从一数组里格式化输入

int vscanf(const char *restrict format,va_list arg);                //同上
int vfscanf(FILE *restrict fp,const char *restrict format,va_list arg);
int vsscanf(const char *restrict buf,const char *restrict format,va_list arg);

int fileno(FILE* fp);    //看_IO_FILE就知道,int _fileno;    这是内部成员,所以一个宏就可以实现//获取文件描述符
 
char *tmpnam(char *ptr);      //产生一个临时文件
FILE *tmpfile(void);          //产生一个流的临时文件

char *tempnam(const char* directory,const char *prefix);     //指定了具体的路径,和前缀,但前缀最多只能5个字符

int mkstemp(char *template);//返回一临时文件的文件描述符.它的前半部应该是先打开临时文件,并返回描述符.


//以下是他最有用的一个文件,来自于glibc-->libio.h,定义了几乎所有重要结构,看我解释
#ifndef _IO_STDIO_H
#define _IO_STDIO_H

#include <_G_config.h>                                //这个不管,一些全局配置,关于下面这个变量的实际定义
/* ALL of these should be defined in _G_config.h */
#define _IO_pos_t _G_fpos_t /* obsolete */          
#define _IO_fpos_t _G_fpos_t
#define _IO_fpos64_t _G_fpos64_t
#define _IO_size_t _G_size_t
#define _IO_ssize_t _G_ssize_t
#define _IO_off_t _G_off_t
#define _IO_off64_t _G_off64_t
#define _IO_pid_t _G_pid_t
#define _IO_uid_t _G_uid_t
#define _IO_iconv_t _G_iconv_t
#define _IO_HAVE_SYS_WAIT _G_HAVE_SYS_WAIT
#define _IO_HAVE_ST_BLKSIZE _G_HAVE_ST_BLKSIZE
#define _IO_BUFSIZ _G_BUFSIZ
#define _IO_va_list _G_va_list
#define _IO_wint_t _G_wint_t

#ifdef _G_NEED_STDARG_H                                        //是否要参数文件,即,它主要实现了va_list,va_start,va_arg,va_end;
/* This define avoids name pollution if we're using GNU stdarg.h */
# define __need___va_list
# include
# ifdef __GNUC_VA_LIST
#  undef _IO_va_list
#  define _IO_va_list __gnuc_va_list
# endif /* __GNUC_VA_LIST */
#endif

#ifndef __P                  //这个我也不知道
# if _G_HAVE_SYS_CDEFS
#  include
# else
#  ifdef __STDC__
#   define __P(p) p
#   define __PMT(p) p
#  else
#   define __P(p) ()
#   define __PMT(p) ()
#  endif
# endif
#endif /*!__P*/

/* For backward compatibility */
#ifndef _PARAMS
# define _PARAMS(protos) __P(protos)
#endif /*!_PARAMS*/

#ifndef __STDC__
# ifndef const
#  define const
# endif
#endif
#define _IO_UNIFIED_JUMPTABLES 1
#ifndef _G_HAVE_PRINTF_FP
# define _IO_USE_DTOA 1
#endif

#ifndef EOF                    //如果没有定义EOF,则定义它为-1
# define EOF (-1)
#endif

#ifndef NULL
# if defined __GNUG__ && \
    (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8))
#  define NULL (__null)
# else
#  if !defined(__cplusplus)         //如果不是C++,则定义为指向0的空指针
#   define NULL ((void*)0)
#  else
#   define NULL (0)                 //如果是c++,则定义NULL为0
#  endif
# endif
#endif

#define _IOS_INPUT 1                //定义一些文件标志宏
#define _IOS_OUTPUT 2
#define _IOS_ATEND 4
#define _IOS_APPEND 8
#define _IOS_TRUNC 16
#define _IOS_NOCREATE 32
#define _IOS_NOREPLACE 64
#define _IOS_BIN 128

/* Magic numbers and bits for the _flags field.              //魔数的一些位为_flag字段.
   The magic numbers use the high-order bits of _flags;
   the remaining bits are available for variable flags.
   Note: The magic numbers must all be negative if stdio     //注意这些魔数必须是相反的,如果stdio仿真是理想的.
   emulation is desired. */

#define _IO_MAGIC 0xFBAD0000 /* Magic number */                 /
#define _OLD_STDIO_MAGIC 0xFABC0000 /* Emulate old stdio. */
#define _IO_MAGIC_MASK 0xFFFF0000
#define _IO_USER_BUF 1 /* User owns buffer; don't delete it on close. */
#define _IO_UNBUFFERED 2
#define _IO_NO_READS 4 /* Reading not allowed */
#define _IO_NO_WRITES 8 /* Writing not allowd */
#define _IO_EOF_SEEN 0x10
#define _IO_ERR_SEEN 0x20
#define _IO_DELETE_DONT_CLOSE 0x40 /* Don't call close(_fileno) on cleanup. */
#define _IO_LINKED 0x80 /* Set if linked (using _chain) to streambuf::_list_all.*/
#define _IO_IN_BACKUP 0x100
#define _IO_LINE_BUF 0x200
#define _IO_TIED_PUT_GET 0x400 /* Set if put and get pointer logicly tied. */
#define _IO_CURRENTLY_PUTTING 0x800
#define _IO_IS_APPENDING 0x1000
#define _IO_IS_FILEBUF 0x2000
#define _IO_BAD_SEEN 0x4000
#define _IO_USER_LOCK 0x8000

#define _IO_FLAGS2_MMAP 1
#define _IO_FLAGS2_NOTCANCEL 2
#ifdef _LIBC
# define _IO_FLAGS2_FORTIFY 4
#endif
#define _IO_FLAGS2_USER_WBUF 8
#ifdef _LIBC
# define _IO_FLAGS2_SCANF_STD 16
#endif

/* These are "formatting flags" matching the iostream fmtflags enum values. */
//这些都是“格式式标志”相匹配的iostream fmtflags枚举值。
#define _IO_SKIPWS 01
#define _IO_LEFT 02
#define _IO_RIGHT 04
#define _IO_INTERNAL 010
#define _IO_DEC 020
#define _IO_OCT 040
#define _IO_HEX 0100
#define _IO_SHOWBASE 0200
#define _IO_SHOWPOINT 0400
#define _IO_UPPERCASE 01000
#define _IO_SHOWPOS 02000
#define _IO_SCIENTIFIC 04000
#define _IO_FIXED 010000
#define _IO_UNITBUF 020000
#define _IO_STDIO 040000
#define _IO_DONT_CLOSE 0100000
#define _IO_BOOLALPHA 0200000

struct _IO_jump_t;  struct _IO_FILE;      //两个声明.

/* Handle lock.  */                       //句柄锁
#ifdef _IO_MTSAFE_IO
# if defined __GLIBC__ && __GLIBC__ >= 2
#  include
# else
/*# include */
# endif
#else
typedef void _IO_lock_t;   //空类型
#endif

/* A streammarker remembers a position in a buffer. */
//一个streammarker记住一个位置在缓冲器。

struct _IO_marker {
  struct _IO_marker *_next;
  struct _IO_FILE *_sbuf;
  /* If _pos >= 0
 it points to _buf->Gbase()+_pos. FIXME comment */
  /* if _pos < 0, it points to _buf->eBptr()+_pos. FIXME comment */
  int _pos;                     
#if 0   //下面C++语法不可能执行
    void set_streampos(streampos sp) { _spos = sp; }
    void set_offset(int offset) { _pos = offset; _spos = (streampos)(-2); }
  public:
    streammarker(streambuf *sb);
    ~streammarker();
    int saving() { return  _spos == -2; }
    int delta(streammarker&);
    int delta();
#endif
};

/* This is the structure from the libstdc++ codecvt class.  */  //来自C++库结构的实现
//设计vc的STL库的那位老大P.J.曾经写过这样的一个转换codecvt,来处理wchar,以免写一个wchar就插入一个全0字节
enum __codecvt_result
{
  __codecvt_ok,
  __codecvt_partial,
  __codecvt_error,
  __codecvt_noconv
};

#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
/* The order of the elements in the following struct must match the order
   of the virtual functions in the libstdc++ codecvt class.  */
struct _IO_codecvt                 //方法表
{
  void (*__codecvt_destr) (struct _IO_codecvt *);
  enum __codecvt_result (*__codecvt_do_out) (struct _IO_codecvt *,
          __mbstate_t *,
          const wchar_t *,
          const wchar_t *,
          const wchar_t **, char *,
          char *, char **);
  enum __codecvt_result (*__codecvt_do_unshift) (struct _IO_codecvt *,
       __mbstate_t *, char *,
       char *, char **);
  enum __codecvt_result (*__codecvt_do_in) (struct _IO_codecvt *,
         __mbstate_t *,
         const char *, const char *,
         const char **, wchar_t *,
         wchar_t *, wchar_t **);
  int (*__codecvt_do_encoding) (struct _IO_codecvt *);
  int (*__codecvt_do_always_noconv) (struct _IO_codecvt *);
  int (*__codecvt_do_length) (struct _IO_codecvt *, __mbstate_t *,
         const char *, const char *, _IO_size_t);
  int (*__codecvt_do_max_length) (struct _IO_codecvt *);

  _IO_iconv_t __cd_in;
  _IO_iconv_t __cd_out;
};

/* Extra data for wide character streams.  */                                        //为宽字节的流定义的额外的数据
struct _IO_wide_data
{
  wchar_t *_IO_read_ptr; /* Current read pointer */            //当前读指针
  wchar_t *_IO_read_end; /* End of get area. */                //末尾读指针
  wchar_t *_IO_read_base; /* Start of putback+get area. */      //开始读的基偏移
  wchar_t *_IO_write_base; /* Start of put area. */
  wchar_t *_IO_write_ptr; /* Current put pointer. */            //当前写指针
  wchar_t *_IO_write_end; /* End of put area. */
  wchar_t *_IO_buf_base; /* Start of reserve area. */
  wchar_t *_IO_buf_end;  /* End of reserve area. */
  /* The following fields are used to support backing up and undo. */
  wchar_t *_IO_save_base; /* Pointer to start of non-current get area. */
  wchar_t *_IO_backup_base; /* Pointer to first valid character of
       backup area */
  wchar_t *_IO_save_end; /* Pointer to end of non-current get area. */

  __mbstate_t _IO_state;
  __mbstate_t _IO_last_state;
  struct _IO_codecvt _codecvt;      //实现流的一些转换操作

  wchar_t _shortbuf[1];

  const struct _IO_jump_t *_wide_vtable;
};
#endif

struct _IO_FILE {                                                                  //传说中的文件流
  int _flags;  /* High-order word is _IO_MAGIC; rest is flags. */         //高字是一些魔数,低字是文件标志.
#define _IO_file_flags _flags           //定义可以使用_flags宏  

  /* The following pointers correspond to the C++ streambuf protocol. */           //下面的指针对应的C + + streambuf协议。
  /* Note:  Tk uses the _IO_read_ptr and _IO_read_end fields directly. */ 

  char* _IO_read_ptr; /* Current read pointer */
  char* _IO_read_end; /* End of get area. */
  char* _IO_read_base; /* Start of putback+get area. */
  char* _IO_write_base; /* Start of put area. */
  char* _IO_write_ptr; /* Current put pointer. */
  char* _IO_write_end; /* End of put area. */
  char* _IO_buf_base; /* Start of reserve area. */
  char* _IO_buf_end; /* End of reserve area. */
  /* The following fields are used to support backing up and undo. */
  char *_IO_save_base; /* Pointer to start of non-current get area. */
  char *_IO_backup_base;  /* Pointer to first valid character of backup area */
  char *_IO_save_end; /* Pointer to end of non-current get area. */

  struct _IO_marker *_markers;

  struct _IO_FILE *_chain;   //流链

  int _fileno;             //文件i_node号
#if 0
  int _blksize;
#else
  int _flags2;            //标志2
#endif
  _IO_off_t _old_offset; /* This used to be _offset but it's too small.  */      //用来存储偏移,但是太小

#define __HAVE_COLUMN /* temporary */         
  /* 1+column number of pbase(); 0 is unknown. */
  unsigned short _cur_column;
  signed char _vtable_offset;
  char _shortbuf[1];

  /*  char* _save_gptr;  char* _save_egptr; */

  _IO_lock_t *_lock;

#ifdef _IO_USE_OLD_IO_FILE           //如果使用旧版本_IO_FILE,则就此结束,否则还下文
};

struct _IO_FILE_complete
{
  struct _IO_FILE _file;
#endif

#if defined _G_IO_IO_FILE_VERSION && _G_IO_IO_FILE_VERSION == 0x20001
  _IO_off64_t _offset;                                                  //如果是新版本则偏移用64位表示
# if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
  /* Wide character stream stuff.  */
  struct _IO_codecvt *_codecvt;
  struct _IO_wide_data *_wide_data; //可见新版本直接处理宽字符流
  struct _IO_FILE *_freeres_list;                                       //已经释放的链表
  void *_freeres_buf; 
  size_t _freeres_size;
# else
  void *__pad1;
  void *__pad2;
  void *__pad3;
  void *__pad4;
  size_t __pad5;
# endif
  int _mode;           //文件模式
  /* Make sure we don't get into trouble again.  */      //末尾添加足够的位,确保数据安全
  char _unused2[15 * sizeof (int) - 4 * sizeof (void *) - sizeof (size_t)];
#endif
};

#ifndef __cplusplus                                //如果是c++,同样使用这个结构
typedef struct _IO_FILE _IO_FILE;                  
#endif

struct _IO_FILE_plus;

extern struct _IO_FILE_plus _IO_2_1_stdin_;      //定义三个导出变量,三个流文件,可以看下面的_IO_FILE_plus
extern struct _IO_FILE_plus _IO_2_1_stdout_;
extern struct _IO_FILE_plus _IO_2_1_stderr_;
#ifndef _LIBC                                       //如果是LIBC,则定义_IO_stdin等三个变量
#define _IO_stdin ((_IO_FILE*)(&_IO_2_1_stdin_))     
#define _IO_stdout ((_IO_FILE*)(&_IO_2_1_stdout_))
#define _IO_stderr ((_IO_FILE*)(&_IO_2_1_stderr_))
#else
extern _IO_FILE *_IO_stdin attribute_hidden;       //如果定义则隐藏_IO_stdin,等三个变量
extern _IO_FILE *_IO_stdout attribute_hidden;
extern _IO_FILE *_IO_stderr attribute_hidden;
#endif


/* Functions to do I/O and file management for a stream.  */     //下面是的流管理功能
/* Read NBYTES bytes from COOKIE into a buffer pointed to by BUF. //读cookie
   Return number of bytes read.  */
/ *读取NBYTES字节来自Cookie从一个缓冲区指针到BUF。
   返回读到字节数。 * /
typedef __ssize_t __io_read_fn (void *__cookie, char *__buf, size_t __nbytes); //定义一个函数,并不是函数指针
/* Write N bytes pointed to by BUF to COOKIE.  Write all N bytes
   unless there is an error.  Return number of bytes written, or -1 if
   there is an error without writing anything.  If the file has been
   opened for append (__mode.__append set), then set the file pointer
   to the end of the file and then do the write; if not, just write at
   the current file pointer.  */
/ *写N字节指出了从缓冲区到COOKIE里。写所有N字节
   除非有一个错误。返回的已经写入字节数,或-1如果
   那里有一个错误没有写入东西。如果该文件打开以APPEND方式( __mode设置__append) ,然后设置文件指针
   到该文件最后,然后写;如果没有,只写在
   当前的文件指针。 * /
typedef __ssize_t __io_write_fn (void *__cookie, __const char *__buf,  //写cookie
     size_t __n);
/* Move COOKIE's file position to *POS bytes from the
   beginning of the file (if W is SEEK_SET),
   the current position (if W is SEEK_CUR),
   or the end of the file (if W is SEEK_END).
   Set *POS to the new file position.
   Returns zero if successful, nonzero if not.  */
移动COOKIE的文件的位置到* POS处,从
   开始的文件(如果W是SEEK_SET ) ,
   当前的位置(如果W是SEEK_CUR ) ,
   或文件的末尾(如果W是SEEK_END ) 。
    设置* POS到新文件的位置。
   返回零如果成功的话,如果不是非零。*/
typedef int __io_seek_fn (void *__cookie, _IO_off64_t *__pos, int __w);//定位COOKIE
/* Close COOKIE.  */
typedef int __io_close_fn (void *__cookie);//关闭COOKIE

#ifdef _GNU_SOURCE      //如果是GNU源代码,就定义下面变量,显然,我们是GNU源代码
/* User-visible names for the above.  */
typedef __io_read_fn cookie_read_function_t;
typedef __io_write_fn cookie_write_function_t;
typedef __io_seek_fn cookie_seek_function_t;
typedef __io_close_fn cookie_close_function_t;

/* The structure with the cookie function pointers.  */
typedef struct
{
  __io_read_fn *read;  /* Read bytes.  */
  __io_write_fn *write;  /* Write bytes.  */
  __io_seek_fn *seek;  /* Seek/tell file position.  */
  __io_close_fn *close;  /* Close file.  */
} _IO_cookie_io_functions_t;
typedef _IO_cookie_io_functions_t cookie_io_functions_t;

struct _IO_cookie_file;

/* Initialize one of those.  */        //初始化上面变量
extern void _IO_cookie_init (struct _IO_cookie_file *__cfile, int __read_write,
        void *__cookie, _IO_cookie_io_functions_t __fns);
#endif

#ifdef __cplusplus   //如果是c++
extern "C" {
#endif

extern int __underflow (_IO_FILE *);        //下溢
extern int __uflow (_IO_FILE *);             //溢出
extern int __overflow (_IO_FILE *, int);        //上溢
#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T   //如果是wchar版本,新版本
extern _IO_wint_t __wunderflow (_IO_FILE *);
extern _IO_wint_t __wuflow (_IO_FILE *);
extern _IO_wint_t __woverflow (_IO_FILE *, _IO_wint_t);
#endif

#if  __GNUC__ >= 3
# define _IO_BE(expr, res) __builtin_expect ((expr), res)
#else
# define _IO_BE(expr, res) (expr)
#endif
                            //以下这些定义十分的重要,标准库很多复杂功能都是来自于下面宏.
                            //下面每个宏几乎是一个函数,libio里文件大都在这些基础上实现
#define _IO_getc_unlocked(_fp) \                                        
       (_IO_BE ((_fp)->_IO_read_ptr >= (_fp)->_IO_read_end, 0) \           //比较当前读指针,大于等末读指针尾溢出,返回新的指针,具体看下篇
 ? __uflow (_fp) : *(unsigned char *) (_fp)->_IO_read_ptr++)
#define _IO_peekc_unlocked(_fp) \                                 //同上,但判断还加上是否文件尾
       (_IO_BE ((_fp)->_IO_read_ptr >= (_fp)->_IO_read_end, 0) \
   && __underflow (_fp) == EOF ? EOF \
 : *(unsigned char *) (_fp)->_IO_read_ptr)
#define _IO_putc_unlocked(_ch, _fp) \                              //将写ch,写到fp里,并返回当前
   (_IO_BE ((_fp)->_IO_write_ptr >= (_fp)->_IO_write_end, 0) \
    ? __overflow (_fp, (unsigned char) (_ch)) \
    : (unsigned char) (*(_fp)->_IO_write_ptr++ = (_ch)))

#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
# define _IO_getwc_unlocked(_fp) \                      //宽字节,具体实现同上
  (_IO_BE ((_fp)->_wide_data->_IO_read_ptr >= (_fp)->_wide_data->_IO_read_end,\
    0) \
   ? __wuflow (_fp) : (_IO_wint_t) *(_fp)->_wide_data->_IO_read_ptr++)
# define _IO_putwc_unlocked(_wch, _fp) \
  (_IO_BE ((_fp)->_wide_data->_IO_write_ptr \
    >= (_fp)->_wide_data->_IO_write_end, 0) \
   ? __woverflow (_fp, _wch) \
   : (_IO_wint_t) (*(_fp)->_wide_data->_IO_write_ptr++ = (_wch)))
#endif

#define _IO_feof_unlocked(__fp) (((__fp)->_flags & _IO_EOF_SEEN) != 0)      //是否文件结束
#define _IO_ferror_unlocked(__fp) (((__fp)->_flags & _IO_ERR_SEEN) != 0)    //判断标志,是否出错
extern int _IO_getc (_IO_FILE *__fp);                 //在libio实现,看下篇
extern int _IO_putc (int __c, _IO_FILE *__fp);
extern int _IO_feof (_IO_FILE *__fp) __THROW;
extern int _IO_ferror (_IO_FILE *__fp) __THROW;

extern int _IO_peekc_locked (_IO_FILE *__fp);

/* This one is for Emacs. */
#define _IO_PENDING_OUTPUT_COUNT(_fp) \
 ((_fp)->_IO_write_ptr - (_fp)->_IO_write_base)

extern void _IO_flockfile (_IO_FILE *) __THROW;
extern void _IO_funlockfile (_IO_FILE *) __THROW;
extern int _IO_ftrylockfile (_IO_FILE *) __THROW;

#ifdef _IO_MTSAFE_IO
# define _IO_peekc(_fp) _IO_peekc_locked (_fp)
# define _IO_flockfile(_fp) \
  if (((_fp)->_flags & _IO_USER_LOCK) == 0) _IO_flockfile (_fp)
# define _IO_funlockfile(_fp) \
  if (((_fp)->_flags & _IO_USER_LOCK) == 0) _IO_funlockfile (_fp)
#else
# define _IO_peekc(_fp) _IO_peekc_unlocked (_fp)
# define _IO_flockfile(_fp) /**/
# define _IO_funlockfile(_fp) /**/
# define _IO_ftrylockfile(_fp) /**/
# define _IO_cleanup_region_start(_fct, _fp) /**/
# define _IO_cleanup_region_end(_Doit) /**/
#endif /* !_IO_MTSAFE_IO */

        //当然这些函数也来自于libio目录下的其他文件
extern int _IO_vfscanf (_IO_FILE * __restrict, const char * __restrict,
   _IO_va_list, int *__restrict);
extern int _IO_vfprintf (_IO_FILE *__restrict, const char *__restrict,
    _IO_va_list);
extern _IO_ssize_t _IO_padn (_IO_FILE *, int, _IO_ssize_t);
extern _IO_size_t _IO_sgetn (_IO_FILE *, void *, _IO_size_t);

extern _IO_off64_t _IO_seekoff (_IO_FILE *, _IO_off64_t, int, int);
extern _IO_off64_t _IO_seekpos (_IO_FILE *, _IO_off64_t, int);

extern void _IO_free_backup_area (_IO_FILE *) __THROW;

#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
extern _IO_wint_t _IO_getwc (_IO_FILE *__fp);
extern _IO_wint_t _IO_putwc (wchar_t __wc, _IO_FILE *__fp);
extern int _IO_fwide (_IO_FILE *__fp, int __mode) __THROW;        ///看上面fwide函数

# if __GNUC__ >= 2
/* While compiling glibc we have to handle compatibility with very old
   versions.  */
#  if defined _LIBC && defined SHARED
#   include
#   if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
#    define _IO_fwide_maybe_incompatible \         //是否是宽字节的,fwide用到它
  (__builtin_expect (&_IO_stdin_used == NULL, 0))
extern const int _IO_stdin_used;
weak_extern (_IO_stdin_used);
#   endif
#  endif
#  ifndef _IO_fwide_maybe_incompatible
#   define _IO_fwide_maybe_incompatible (0)
#  endif
/* A special optimized version of the function above.  It optimizes the
   case of initializing an unoriented byte stream.  */

#  define _IO_fwide(__fp, __mode) \        //改变流模式这里已经实现了
  ({ int __result = (__mode);            \
     if (__result < 0 && ! _IO_fwide_maybe_incompatible)        \
       {              \
  if ((__fp)->_mode == 0)           \
    /* We know that all we have to do is to set the flag.  */       \
    (__fp)->_mode = -1;            \
  __result = (__fp)->_mode;           \
       }              \
     else if (__builtin_constant_p (__mode) && (__mode) == 0)        \
       __result = _IO_fwide_maybe_incompatible ? -1 : (__fp)->_mode;       \
     else              \
       __result = _IO_fwide (__fp, __result);          \
     __result; })
# endif

extern int _IO_vfwscanf (_IO_FILE * __restrict, const wchar_t * __restrict,
    _IO_va_list, int *__restrict);
extern int _IO_vfwprintf (_IO_FILE *__restrict, const wchar_t *__restrict,
     _IO_va_list);
extern _IO_ssize_t _IO_wpadn (_IO_FILE *, wint_t, _IO_ssize_t);
extern void _IO_free_wbackup_area (_IO_FILE *) __THROW;
#endif

#ifdef __LDBL_COMPAT
# include
#endif

#ifdef __cplusplus
}
#endif

#endif /* _IO_STDIO_H */

阅读(1126) | 评论(0) | 转发(0) |
0

上一篇:Inf文件

下一篇:文件和目录

给主人留下些什么吧!~~