fstat and similar methods in fhandler_socket_local and fhandler_socket_unix

Corinna Vinschen corinna-cygwin@cygwin.com
Thu Feb 25 17:03:37 GMT 2021


On Feb 25 08:18, Ken Brown via Cygwin-developers wrote:
> While working on this, I discovered that linkat(AT_EMPTY_PATH) doesn't
> currently work on socket files opened with O_PATH.  I started debugging this
> (not finished yet), and it occurred to me that the implementation of
> linkat(AT_EMPTY_PATH) could be simplified like this:
> 
> --- a/winsup/cygwin/syscalls.cc
> +++ b/winsup/cygwin/syscalls.cc
> @@ -4962,6 +4962,8 @@ linkat (int olddirfd, const char *oldpathname,
>         int flags)
>  {
>    tmp_pathbuf tp;
> +  fhandler_base *fh = NULL;
> +
>    __try
>      {
>        if (flags & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH))
> @@ -4970,21 +4972,19 @@ linkat (int olddirfd, const char *oldpathname,
>           __leave;
>         }
>        char *oldpath = tp.c_get ();
> -      /* AT_EMPTY_PATH with an empty oldpathname is equivalent to
> -
> -          linkat(AT_FDCWD, "/proc/self/fd/<olddirfd>", newdirfd,
> -                 newname, AT_SYMLINK_FOLLOW);
> -
> -        Convert the request accordingly. */
>        if ((flags & AT_EMPTY_PATH) && oldpathname && oldpathname[0] == '\0')
>         {
> +         /* Operate directly on olddirfd. */
>           if (olddirfd == AT_FDCWD)
>             {
>               set_errno (EPERM);
>               __leave;
>             }
> -         __small_sprintf (oldpath, "/proc/%d/fd/%d", myself->pid, olddirfd);
> -         flags = AT_SYMLINK_FOLLOW;
> +         cygheap_fdget cfd (olddirfd);
> +         if (cfd < 0)
> +           __leave;
> +         fh = cfd;
> +         flags = 0;
>         }
>        else if (gen_full_path_at (oldpath, olddirfd, oldpathname))
>         __leave;
> @@ -5003,6 +5003,8 @@ linkat (int olddirfd, const char *oldpathname,
>             }
>           strcpy (oldpath, old_name.get_posix ());
>         }
> +      if (fh)
> +       return fh->link (newpath);
>        return link (oldpath, newpath);
>      }
>    __except (EFAULT) {}

Good idea.  Just a small comment why you set flags to 0 might be nice.

> This seems to work fine on regular files and on socket files opened with
> O_PATH, after I tweak fhandler_socket_local::link (see below).  I haven't
> tested other file types yet.

For most of them that should end up in fhandler_base:link anyway.


Thanks,
Corinna


More information about the Cygwin-developers mailing list