glibc源码分析之chdir,fchdir,chroot,getcwd

chdir,fchdir函数用于修改进程的当前工作目录。它们是由脚本生成的:

#define SYSCALL_NAME chdir
#define SYSCALL_NARGS 1
#define SYSCALL_SYMBOL __chdir
#define SYSCALL_CANCELLABLE 0
#define SYSCALL_NOERRNO 0
#define SYSCALL_ERRVAL 0
#include <syscall-template.S>
weak_alias (__chdir, chdir)
hidden_weak (chdir)
#define SYSCALL_NAME fchdir
#define SYSCALL_NARGS 1
#define SYSCALL_SYMBOL __fchdir
#define SYSCALL_CANCELLABLE 0
#define SYSCALL_NOERRNO 0
#define SYSCALL_ERRVAL 0
#include <syscall-template.S>
weak_alias (__fchdir, fchdir)
hidden_weak (fchdir)

chroot函数用于更改进程的当前目录。它是由脚本生成的。

#define SYSCALL_NAME chroot
#define SYSCALL_NARGS 1
#define SYSCALL_SYMBOL chroot
#define SYSCALL_CANCELLABLE 0
#define SYSCALL_NOERRNO 0
#define SYSCALL_ERRVAL 0
#include <syscall-template.S>

getcwd函数用于获取进程的当前工作目录。getcwd不是简单的封装系统调用,而是做了语义上的修改。这使得getcwd函数比其他函数更复杂。

getcwd源码:

char *
__getcwd (char *buf, size_t size)
{
  char *path;
  char *result;

  //确定缓冲区的长度
  size_t alloc_size = size;
  if (size == 0)
    {
      if (buf != NULL)
    {
      __set_errno (EINVAL);
      return NULL;
    }

      alloc_size = MAX (PATH_MAX, __getpagesize ());
    }
  //申请缓冲区
  if (buf == NULL)
    {
      path = malloc (alloc_size);
      if (path == NULL)
        return NULL;
    }
  else
    path = buf;

  int retval;
  //调用系统调用获取当前工作目录
  retval = INLINE_SYSCALL (getcwd, 2, path, alloc_size);
  //获取成功
  if (retval >= 0)
    {
      //重新设置缓冲区
      if (buf == NULL && size == 0)
          buf = realloc (path, (size_t) retval);

      if (buf == NULL)
        buf = path;

      return buf;
    }

   //如果出错了,且出错原因是文件路径太长,则执行generic_getcwd获取当前文件路径。 generic_getcwd是内部函数,源码不可见。
  if (errno == ENAMETOOLONG)
    {

      if (buf == NULL && size == 0)
      {
          free (path);
          path = NULL;
      }


      result = generic_getcwd (path, size);


      if (result == NULL && buf == NULL && size != 0)
           free (path);


      return result;
    }

  assert (errno != ERANGE || buf != NULL || size != 0);

  if (buf == NULL)
    free (path);

  return NULL;
}
weak_alias (__getcwd, getcwd)
发布了185 篇原创文章 · 获赞 18 · 访问量 16万+

猜你喜欢

转载自blog.csdn.net/pk_20140716/article/details/77429468
今日推荐