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

时间:2019-12-06 01:42:57

标签: c system-calls errno

从男人那里打开:

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

...

       ENAMETOOLONG
              pathname was too long.

openerrno设置为ENAMETOOLONG,但是我在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;                                  \
  })

1 个答案:

答案 0 :(得分:1)

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