fstat and similar methods in fhandler_socket_local and fhandler_socket_unix
Ken Brown
kbrown@cornell.edu
Wed Feb 24 15:32:23 GMT 2021
On 2/24/2021 4:06 AM, Corinna Vinschen via Cygwin-developers wrote:
> On Feb 22 15:01, Ken Brown via Cygwin-developers wrote:
>> OK, I've got patches ready to go for fstat, fstatvfs, fchmod, fchown, facl,
>> and link. I have to test them, and then I'll send them to cygwin-patches.
>> In the case of link, I think the only way an fhandler_socket's link method
>> can be called is through link(2) being called on a socket file. So the
>> following should do the job:
>>
>> diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
>> index 21e1df172..f4aa12956 100644
>> --- a/winsup/cygwin/fhandler.h
>> +++ b/winsup/cygwin/fhandler.h
>> @@ -611,7 +611,6 @@ class fhandler_socket: public fhandler_base
>> int __reg1 fchmod (mode_t newmode);
>> int __reg2 fchown (uid_t newuid, gid_t newgid);
>> int __reg3 facl (int, int, struct acl *);
>> - int __reg2 link (const char *);
>> off_t lseek (off_t, int)
>> {
>> set_errno (ESPIPE);
>> diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc
>> index f22412650..08870cc6b 100644
>> --- a/winsup/cygwin/fhandler_socket.cc
>> +++ b/winsup/cygwin/fhandler_socket.cc
>> @@ -357,9 +357,3 @@ fhandler_socket::facl (int cmd, int nentries, aclent_t *aclbufp)
>> set_errno (EOPNOTSUPP);
>> return -1;
>> }
>> -
>> -int
>> -fhandler_socket::link (const char *newpath)
>> -{
>> - return fhandler_base::link (newpath);
>> -}
>
> Hmm. What about linkat (AT_EMPTY_PATH, socket, ...)?
>
> This could be called for inet sockets as well as unnamed or abstract
> unix sockets, in theory...
Thanks, I missed that case. So we do need fhandler_socket::link. The only
question in my mind is what errno it should set. I just tried the following:
$ cat socket_linkat.c
#define _GNU_SOURCE
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#define NEW_PATH "/tmp/newpath"
int
main ()
{
struct sockaddr_un addr;
int fd;
if (unlink (NEW_PATH) == -1 && errno != ENOENT)
{
perror ("unlink");
exit (1);
}
fd = socket (AF_UNIX, SOCK_STREAM, 0);
if (fd == -1)
{
perror ("socket");
exit (1);
}
if (linkat (fd, "", AT_FDCWD, NEW_PATH, AT_EMPTY_PATH) == -1)
perror ("linkat");
}
On Linux I get
linkat: Invalid cross-device link
So I think fhandler_socket::link should fail with EXDEV. Probably it should
continue to call fhandler_base::link, and the latter should fail with EXDEV
instead of EPERM. Or is there some case where EPERM is more appropriate?
Ken
More information about the Cygwin-developers
mailing list