glibc源码分析之文件的创建与删除

glibc中与文件创建与删除有关的函数有creat,open,unlink,mkdir,rmdir,mknod,symlink,link。

文件类型 创建 删除
普通文件 creat/mknod unlink
目录文件 mkdir rmdir
字符设备文件 mknod unlink
块设备文件 mknod unlink
管道文件 mknod unlink
套接字文件 mknod unlink
符号链接文件 symlink unlink

这些函数都有对应的系统调用,函数对它们进行了封装。

其中unlink,mkdir,rmdir,symlink,link是用脚本生成的。它们生成的.S文件如下:

#define SYSCALL_NAME unlink
#define SYSCALL_NARGS 1
#define SYSCALL_SYMBOL __unlink
#define SYSCALL_CANCELLABLE 0
#define SYSCALL_NOERRNO 0
#define SYSCALL_ERRVAL 0
#include <syscall-template.S>
weak_alias (__unlink, unlink)
hidden_weak (unlink)
#define SYSCALL_NAME mkdir
#define SYSCALL_NARGS 2
#define SYSCALL_SYMBOL __mkdir
#define SYSCALL_CANCELLABLE 0
#define SYSCALL_NOERRNO 0
#define SYSCALL_ERRVAL 0
#include <syscall-template.S>
weak_alias (__mkdir, mkdir)
hidden_weak (mkdir)
#define SYSCALL_NAME rmdir
#define SYSCALL_NARGS 1
#define SYSCALL_SYMBOL __rmdir
#define SYSCALL_CANCELLABLE 0
#define SYSCALL_NOERRNO 0
#define SYSCALL_ERRVAL 0
#include <syscall-template.S>
weak_alias (__rmdir, rmdir)
hidden_weak (rmdir)
#define SYSCALL_NAME symlink
#define SYSCALL_NARGS 2
#define SYSCALL_SYMBOL __symlink
#define SYSCALL_CANCELLABLE 0
#define SYSCALL_NOERRNO 0
#define SYSCALL_ERRVAL 0
#include <syscall-template.S>
weak_alias (__symlink, symlink)
hidden_weak (symlink)
#define SYSCALL_NAME link
#define SYSCALL_NARGS 2
#define SYSCALL_SYMBOL __link
#define SYSCALL_CANCELLABLE 0
#define SYSCALL_NOERRNO 0
#define SYSCALL_ERRVAL 0
#include <syscall-template.S>
weak_alias (__link, link)
hidden_weak (link)

creat,open,mknod是.c文件生成。

open函数位于sysdeps/unix/sysv/linux/open.c文件中。

int
__libc_open (const char *file, int oflag, ...)
{
  int mode = 0;

  if (__OPEN_NEEDS_MODE (oflag))
    {
      va_list arg;
      va_start (arg, oflag);
      mode = va_arg (arg, int);
      va_end (arg);
    }

  return SYSCALL_CANCEL (openat, AT_FDCWD, file, oflag, mode);
}
libc_hidden_def (__libc_open)

weak_alias (__libc_open, __open)
libc_hidden_weak (__open)
weak_alias (__libc_open, open)

open函数调用openat系统调用完成封装。如果需要model参数,则从栈中取出。

creat函数位于sysdeps/unix/sysv/linux/creat.c文件中。

int
__creat (const char *file, mode_t mode)
{
  return SYSCALL_CANCEL (creat, file, mode);
}
weak_alias (__creat, creat)

creat函数调用creat系统调用完成封装。

mknod函数位于io/mknod.c文件中

int
attribute_hidden
__mknod (const char *path, mode_t mode, dev_t dev)
{
  return __xmknod (_MKNOD_VER, path, mode, &dev);
}

weak_hidden_alias (__mknod, mknod)

__mknod函数调用了__xmknod 函数,__xmknod 函数位于sysdeps/unix/sysv/linux/xmknod.c文件中。

int
__xmknod (int vers, const char *path, mode_t mode, dev_t *dev)
{
  unsigned long long int k_dev;

  if (vers != _MKNOD_VER)
    return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL);

  /* We must convert the value to dev_t type used by the kernel.  */
  k_dev =  (*dev) & ((1ULL << 32) - 1);
  if (k_dev != *dev)
    return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL);

  return INLINE_SYSCALL (mknod, 3, path, mode, (unsigned int) k_dev);
}

weak_alias (__xmknod, _xmknod)
libc_hidden_def (__xmknod)

__xmknod 调用了mknod系统调用完成封装。

发布了185 篇原创文章 · 获赞 18 · 访问量 16万+

猜你喜欢

转载自blog.csdn.net/pk_20140716/article/details/77268540