glibc的stat关系函数有stat、fstat、lstat。 这些都是系统调用的封装函数。
与stat有关的系统调用包括oldstat18 )、oldstat18 )、oldstat18 )、stat 16 )、lstat 17 )、fstat 108 )、stat 19.5 ) stat64系列系统调用用于获取文件属性,文件属性为32位。 另一方面,stat64系列系统调用用于获取64位文件属性。 因此,stat系列系统调用无法获取长度超过32位的文件的属性。
使用stat64系列系统调用封装stat、fstat和lstat函数,而不是stat系列系统调用。
显示stat函数的源代码:
#undef stat
资讯科技
attribute_hidden
_ _ stat 常数字符文件,结构开始*总线) ) ) ) ) ) ) ) )。
{
return__xstat_stat_ver,file,buf );
}
) ) ) )。
函数__stat调用了__xstat函数。 __xstat函数在sys deps/UNIX/sysv/Linux/i386/xstat.c文件中定义。
资讯科技
__xstatintVers,const char *name,struct stat *buf ) ) ) ) ) ) ) ) )
{
int result;
ifVERS==_stat_ver_kernel ) ) )。
returninline_syscallstat,2,name,buf );
{
严格启动64 buf 64;
内部_ syscall _ decl err;
result=internal_syscallstat64,err,2,name,buf64 );
if _ glibc _ unlikely internal _ syscall _ error _ p ) result,err ) )
返回线_ syscall _ error _ return _ value internal _ syscall _ errno ) result,
err );
else
return__xstat32_convVERS,buf64,buf );
}
}
hidden_def_xstat ) ) )。
weak_alias_xstat,_xstat );
如果参数vers等于_STAT_VER_KERNEL,则直接调用stat系统调用。 很明显,__stat传递的参数是_STAT_VER。
__xstat函数首先调用stat64系统调用以获取文件属性。 然后,判断返回值是否为错误,如果为错误,则返回-1,并设置errno。 如果成功执行,文件属性将转换为32位,并返回0。
文件属性转换源代码:
资讯科技
__xstat32_convintVERS,struct stat64 *kbuf,struct stat *buf ) ) ) ) ) 0
{
是交换机vers )
{
case _STAT_VER_LINUX:
{
buf-st_dev=kbuf-st_dev;
#ifdef _HAVE_STAT___PAD1
buf-__pad1=0;
#endif
#ifdef _HAVE_STAT64___ST_INO
# if! __ASSUME_ST_INO_64_BIT
ifkbuf-ST_ino==0) ) ) ) )。
buf-st_ino=kbuf-__st_ino;
else
# endif
{
buf-st_ino=kbuf-st_ino;
ifsizeofbuf-ST_ino )!=sizeofkbuf-ST_ino ) )
buf-st_ino!=kbuf-st_ino )
return inline _ syscall _ error _ return _ value 环境溢出;
}
#else
buf-st_ino=kbuf-st_ino;
ifsizeofbuf-ST_ino )!=Sizeofkbuf-
st_ino)
&& buf->st_ino != kbuf->st_ino)
return INLINE_SYSCALL_ERROR_RETURN_VALUE EOVERFLOW);
#endif
buf->st_mode = kbuf->st_mode;
buf->st_nlink = kbuf->st_nlink;
buf->st_uid = kbuf->st_uid;
buf->st_gid = kbuf->st_gid;
buf->st_rdev = kbuf->st_rdev;
#ifdef _HAVE_STAT___PAD2
buf->__pad2 = 0;
#endif
buf->st_size = kbuf->st_size;
/* Check for overflow. */
if sizeof buf->st_size) != sizeof kbuf->st_size)
&& buf->st_size != kbuf->st_size)
return INLINE_SYSCALL_ERROR_RETURN_VALUE EOVERFLOW);
buf->st_blksize = kbuf->st_blksize;
buf->st_blocks = kbuf->st_blocks;
/* Check for overflow. */
if sizeof buf->st_blocks) != sizeof kbuf->st_blocks)
&& buf->st_blocks != kbuf->st_blocks)
return INLINE_SYSCALL_ERROR_RETURN_VALUE EOVERFLOW);
#ifdef _HAVE_STAT_NSEC
buf->st_atim.tv_sec = kbuf->st_atim.tv_sec;
buf->st_atim.tv_nsec = kbuf->st_atim.tv_nsec;
buf->st_mtim.tv_sec = kbuf->st_mtim.tv_sec;
buf->st_mtim.tv_nsec = kbuf->st_mtim.tv_nsec;
buf->st_ctim.tv_sec = kbuf->st_ctim.tv_sec;
buf->st_ctim.tv_nsec = kbuf->st_ctim.tv_nsec;
#else
buf->st_atime = kbuf->st_atime;
buf->st_mtime = kbuf->st_mtime;
buf->st_ctime = kbuf->st_ctime;
#endif
#ifdef _HAVE_STAT___UNUSED1
buf->__glibc_reserved1 = 0;
#endif
#ifdef _HAVE_STAT___UNUSED2
buf->__glibc_reserved2 = 0;
#endif
#ifdef _HAVE_STAT___UNUSED3
buf->__glibc_reserved3 = 0;
#endif
#ifdef _HAVE_STAT___UNUSED4
buf->__glibc_reserved4 = 0;
#endif
#ifdef _HAVE_STAT___UNUSED5
buf->__glibc_reserved5 = 0;
#endif
}
break;
/* If struct stat64 is different from struct stat then
_STAT_VER_KERNEL does not make sense. */
case _STAT_VER_KERNEL:
default:
return INLINE_SYSCALL_ERROR_RETURN_VALUE EINVAL);
}
return 0;
}
#define _STAT_VER_LINUX 3
#define _STAT_VER _STAT_VER_LINUX /* The one defined below. */
fstat函数源码:
#undef fstat
#undef __fstat
int
attribute_hidden
__fstat int fd, struct stat *buf)
{
return __fxstat _STAT_VER, fd, buf);
}
weak_hidden_alias __fstat, fstat)
__fstat函数调用了__fxstat 函数。而__fxstat 函数定义在sysdeps/unix/sysv/linux/i386/fxstat.c文件中。
int
__fxstat int vers, int fd, struct stat *buf)
{
int result;
if vers == _STAT_VER_KERNEL)
return INLINE_SYSCALL fstat, 2, fd, buf);
{
struct stat64 buf64;
INTERNAL_SYSCALL_DECL err);
result = INTERNAL_SYSCALL fstat64, err, 2, fd, &buf64);
if __glibc_unlikely INTERNAL_SYSCALL_ERROR_P result, err)))
return INLINE_SYSCALL_ERROR_RETURN_VALUE INTERNAL_SYSCALL_ERRNO result,
err));
else
return __xstat32_conv vers, &buf64, buf);
}
}
hidden_def __fxstat)
weak_alias __fxstat, _fxstat);
__fxstat 函数调用过程类似于__xstat函数。
lstat函数源码:
#undef lstat
#undef __lstat
int
attribute_hidden
__lstat const char *file, struct stat *buf)
{
return __lxstat _STAT_VER, file, buf);
}
weak_hidden_alias __lstat, lstat)
__lstat函数调用了__fxstat 函数。而__lxstat 函数定义在sysdeps/unix/sysv/linux/i386/lxstat.c文件中。
int
__lxstat int vers, const char *name, struct stat *buf)
{
int result;
if vers == _STAT_VER_KERNEL)
return INLINE_SYSCALL lstat, 2, name, buf);
{
struct stat64 buf64;
INTERNAL_SYSCALL_DECL err);
result = INTERNAL_SYSCALL lstat64, err, 2, name, &buf64);
if __glibc_unlikely INTERNAL_SYSCALL_ERROR_P result, err)))
return INLINE_SYSCALL_ERROR_RETURN_VALUE INTERNAL_SYSCALL_ERRNO result,
err));
else
return __xstat32_conv vers, &buf64, buf);
}
}
hidden_def __lxstat)
weak_alias __lxstat, _lxstat);
__lxstat 函数调用过程类似于__xstat函数。