glibc-2.15 : fseek 源码

最近使用fseek时遇到一个问题,fseek的函数原型如下:

 int fseek(FILE *stream, long offset, int whence);

可是我在使用的时候犯了一个错误,我把fseek的第二个参数和第三个参数的位置弄错了。

而且我没有检测fseek的返回值,导致程序出错。(发现自己太low了.......)

为此我首先查看了当前环境的glibc的版本。

直接运行libc.so.6会输出glibc的版本,或者使用 “ldd --version”也是可以的,我的glibc的版本是 2.15

huntinux@ubuntu-chj:~/Downloads/glibc-2.15$ /lib/x86_64-linux-gnu/libc.so.6 
GNU C Library (Ubuntu EGLIBC 2.15-0ubuntu10.12) stable release version 2.15, by Roland McGrath et al.
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 4.6.3.
Compiled on a Linux 3.2.68 system on 2015-03-26.
Available extensions:
	crypt add-on version 2.1 by Michael Glad and others
	GNU Libidn by Simon Josefsson
	Native POSIX Threads Library by Ulrich Drepper et al
	BIND-8.2.3-T5B
libc ABIs: UNIQUE IFUNC
For bug reporting instructions, please see:
<http://www.debian.org/Bugs/>.

 

于是我下载了glibc-2.15的源码找到了fseek的源码

/* ./libio/fseek.c */
int
fseek (fp, offset, whence)
    _IO_FILE* fp;
    long int offset;
    int whence;
{
    int result;
    CHECK_FILE (fp, -1);
    _IO_acquire_lock (fp);
    result = _IO_fseek (fp, offset, whence);
    _IO_release_lock (fp);
    return result;
}

/*  libio/iolibio.h  */
#define _IO_fseek(__fp, __offset, __whence) \
  (_IO_seekoff_unlocked (__fp, __offset, __whence, _IOS_INPUT|_IOS_OUTPUT) \
   == _IO_pos_BAD ? EOF : 0)

/* libio/libioP.h */
#define _IO_seek_set 0
#define _IO_seek_cur 1
#define _IO_seek_end 2

/* posix/unistd.h */
# define SEEK_SET   0   /* Seek from beginning of file.  */
# define SEEK_CUR   1   /* Seek from current position.  */
# define SEEK_END   2   /* Seek from end of file.  */


/*  libio/ioseekoff.c */
_IO_off64_t
_IO_seekoff_unlocked (fp, offset, dir, mode)
     _IO_FILE *fp;
     _IO_off64_t offset;
     int dir;
     int mode;
{
  if (dir != _IO_seek_cur && dir != _IO_seek_set && dir != _IO_seek_end)
    {
      __set_errno (EINVAL);
      return EOF;
    }

  /* If we have a backup buffer, get rid of it, since the __seekoff
     callback may not know to do the right thing about it.
     This may be over-kill, but it'll do for now. TODO */
  if (mode != 0 && ((_IO_fwide (fp, 0) < 0 && _IO_have_backup (fp))
            || (_IO_fwide (fp, 0) > 0 && _IO_have_wbackup (fp))))
    {
      if (dir == _IO_seek_cur && _IO_in_backup (fp))
    {
      if (_IO_vtable_offset (fp) != 0 || fp->_mode <= 0)
        offset -= fp->_IO_read_end - fp->_IO_read_ptr;
      else
        abort ();
    }
      if (_IO_fwide (fp, 0) < 0)
    INTUSE(_IO_free_backup_area) (fp);
      else
    INTUSE(_IO_free_wbackup_area) (fp);
    }

  return _IO_SEEKOFF (fp, offset, dir, mode);
}

其中:

  if (dir != _IO_seek_cur && dir != _IO_seek_set && dir != _IO_seek_end)
    {
      __set_errno (EINVAL);
      return EOF;
    }
是检查fseek的第三个参数whence的值,是否为 SEEK_CUR SEEK_SET SEEK_END。 如果不是就返回EOF(-f), 并设置错误码为EINVAL。

这与manpage中的描述是一致的。

man page是这样写的:

RETURN VALUE
       The rewind() function returns no value.  Upon successful completion, fgetpos(), fseek(), fsetpos() return 0, and ftell() returns the current offset.   Oth‐
       erwise, -1 is returned and errno is set to indicate the error.

ERRORS
       EBADF  The stream specified is not a seekable stream.

       EINVAL The whence argument to fseek() was not SEEK_SET, SEEK_END, or SEEK_CUR.

总结

养成良好的习惯,要检查函数返回值!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值