繁体   English   中英

当路径名太长时,glibc 的 syscall 实现在哪里打开设置 ENAMETOOLONG errno?

[英]where does the glibc's implementation of syscall open set ENAMETOOLONG errno when pathname is too long?

从男人打开:

int open(const char *pathname, int flags);

...

       ENAMETOOLONG
              pathname was too long.

openerrnoENAMETOOLONG ,但我在 glibc 的源代码中找不到这个赋值(也许它会调用内核函数,但我也找不到)

下面是我已经在 glibc 中探索过的函数:

/* Open FILE with access OFLAG.  If O_CREAT or O_TMPFILE is in OFLAG,
   a third argument is the file protection.  */
int
__libc_open (const char *file, int oflag)
{
  int mode;

  if (file == NULL)
    {
      __set_errno (EINVAL);
      return -1;
    }

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

  __set_errno (ENOSYS);
  return -1;
}
int
__open_nocancel (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 INLINE_SYSCALL_CALL (openat, AT_FDCWD, file, oflag, mode);
}
/* Open FILE with access OFLAG.  Interpret relative paths relative to
   the directory associated with FD.  If O_CREAT or O_TMPFILE is in OFLAG, a
   third argument is the file protection.  */
int
__openat (int fd, const char *file, int oflag, ...)
{
  int mode;

  if (file == NULL)
    {
      __set_errno (EINVAL);
      return -1;
    }

  if (fd != AT_FDCWD && file[0] != '/')
    {
      /* Check FD is associated with a directory.  */
      struct stat64 st;
      if (__fxstat64 (_STAT_VER, fd, &st) != 0)
    return -1;

      if (!S_ISDIR (st.st_mode))
    {
      __set_errno (ENOTDIR);
      return -1;
    }
    }

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

      ignore_value (mode);
    }

  __set_errno (ENOSYS);
  return -1;
}
/* Issue a syscall defined by syscall number plus any other argument
   required.  Any error will be handled using arch defined macros and errno
   will be set accordingly.
   It is similar to INLINE_SYSCALL macro, but without the need to pass the
   expected argument number as second parameter.  */
#define INLINE_SYSCALL_CALL(...) \
  __INLINE_SYSCALL_DISP (__INLINE_SYSCALL, __VA_ARGS__)

#define SYSCALL_CANCEL(...) \
  ({                                         \
    long int sc_ret;                                 \
    if (SINGLE_THREAD_P)                             \
      sc_ret = INLINE_SYSCALL_CALL (__VA_ARGS__);                \
    else                                     \
      {                                      \
    int sc_cancel_oldtype = LIBC_CANCEL_ASYNC ();                \
    sc_ret = INLINE_SYSCALL_CALL (__VA_ARGS__);              \
        LIBC_CANCEL_RESET (sc_cancel_oldtype);                   \
      }                                      \
    sc_ret;                                  \
  })

它由文件系统处理,因为名称太长的规则可能非常复杂且特定于文件系统。 例如,请参阅 EXT4 中的此代码

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM