十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
libio/sebuf.c定义了sebbuf函数:
成都创新互联公司是一家专注于成都网站建设、做网站与策划设计,麻阳网站建设哪家好?成都创新互联公司做网站,专注于网站建设十载,网设计领域的专业建站公司;建站业务涵盖:麻阳等地区。麻阳做网站价格咨询:028-86922220
void setbuf (FILE *fp, char *buf)
{
_IO_setbuffer (fp, buf, BUFSIZ);
}
libio/iosetbuffer.c定义了_IO_setbuffer函数:
void _IO_setbuffer (FILE *fp, char *buf, size_t size)
{
CHECK_FILE (fp, );
_IO_acquire_lock (fp);
fp->_flags &= ~_IO_LINE_BUF;
if (!buf)
size = 0;
(void) _IO_SETBUF (fp, buf, size);
if (_IO_vtable_offset (fp) == 0 && fp->_mode == 0 && _IO_CHECK_WIDE (fp))
/* We also have to set the buffer using the wide char function. */
(void) _IO_WSETBUF (fp, buf, size);
_IO_release_lock (fp);
}
除了锁定FILE指针外,核心代码就是_IO_SETBUF和用于多字节环境的_IO_WSETBUF,最后解析,重点介绍下_IO_SETBUF
libio/libioP.h定义了_IO_SETBUF和_IO_WSETBUF:
typedef FILE* (*_IO_setbuf_t) (FILE *, char *, ssize_t);
#define _IO_SETBUF(FP, BUFFER, LENGTH) JUMP2 (__setbuf, FP, BUFFER, LENGTH)
#define _IO_WSETBUF(FP, BUFFER, LENGTH) WJUMP2 (__setbuf, FP, BUFFER, LENGTH)
#define JUMP2(FUNC, THIS, X1, X2) (_IO_JUMPS_FUNC(THIS)->FUNC) (THIS, X1, X2)
#define WJUMP2(FUNC, THIS, X1, X2) (_IO_WIDE_JUMPS_FUNC(THIS)->FUNC) (THIS, X1, X2)
struct _IO_FILE_plus
{
FILE file;
const struct _IO_jump_t *vtable;
};
1)_IO_JUMPS_FUNC(THIS)是通过_IO_CAST_FIELD_ACCESS将setbuf函数的参数fp转成struct _IO_FILE_plus类型,
并返回struct _IO_FILE_plus的vtable变量,通过vtable调用__setbuf函数(JUMP2的参数),
2)通过JUMP_INIT (setbuf, _IO_default_setbuf)定义了vtable默认的__setbuf函数
4. libio/genops.c定义了_IO_default_setbuf及其调用的_IO_setb,_IO_setb设置了setbuf函数的参数fp的_IO_buf_base等buf变量:
FILE * _IO_default_setbuf (FILE *fp, char *p, ssize_t len)
{
if (_IO_SYNC (fp) == EOF)
return NULL;
if (p == NULL || len == 0)
{
fp->_flags |= _IO_UNBUFFERED;
_IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
}
else
{
fp->_flags &= ~_IO_UNBUFFERED;
_IO_setb (fp, p, p+len, 0);
}
fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = 0;
fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_read_end = 0;
return fp;
}
void _IO_setb (FILE *f, char *b, char *eb, int a)
{
if (f->_IO_buf_base && !(f->_flags & _IO_USER_BUF))
free (f->_IO_buf_base);
f->_IO_buf_base = b;
f->_IO_buf_end = eb;
if (a)
f->_flags &= ~_IO_USER_BUF;
else
f->_flags |= _IO_USER_BUF;
}