File 0003-server-Allow-for-deletion-of-socket-files.patch of Package wine

From 1ee5baf3bec552b4ebf24434b9ea8946e753f44e Mon Sep 17 00:00:00 2001
From: Ally Sommers <dropbear.sh@gmail.com>
Date: Wed, 10 May 2023 18:23:20 +0000
Subject: [PATCH 3/9] server: Allow for deletion of socket files.

Deleting the socket file is a common pattern with
AF_UNIX sockets, and is analogous to unbinding.

Ugliness removed by Ralf Habacker.
---
 server/fd.c | 32 ++++++++++++++++++++++++++++----
 1 file changed, 28 insertions(+), 4 deletions(-)

diff --git a/server/fd.c b/server/fd.c
index 6c71336247f..ecb9bf570f2 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -1984,22 +1984,43 @@ struct fd *open_fd( struct fd *root, const char *name, struct unicode_str nt_nam
 
         if (fd->unix_fd == -1)
         {
+            if (stat( name, &st ))
+            {
+                file_set_error();
+                goto error;
+            }
+
             /* check for trailing slash on file path */
             if ((errno == ENOENT || (errno == ENOTDIR && !(options & FILE_DIRECTORY_FILE))) && name[strlen(name) - 1] == '/')
+            {
                 set_error( STATUS_OBJECT_NAME_INVALID );
+                goto error;
+            }
+            /* POSIX requires that open(2) throws EOPNOTSUPP when `path` is a Unix
+             * socket. BSD throws EOPNOTSUPP in this case and the additional case of
+             * O_SHLOCK or O_EXLOCK being passed when `path` resides on a filesystem
+             * without lock support. Contrary to POSIX, Linux returns ENXIO in this
+             * case, so we also check that error code here.
+             */
+            else if ((errno == EOPNOTSUPP || errno == ENXIO) && S_ISSOCK(st.st_mode) && (options & FILE_DELETE_ON_CLOSE))
+                ; /* no error, go to regular deletion code path */
             else
+            {
                 file_set_error();
-            goto error;
+                goto error;
+            }
         }
     }
 
     fd->nt_name = dup_nt_name( root, nt_name, &fd->nt_namelen );
     fd->unix_name = NULL;
-    fstat( fd->unix_fd, &st );
+    /* st was set from the file name if the file could not be opened */
+    if (fd->unix_fd != -1)
+        fstat( fd->unix_fd, &st );
     *mode = st.st_mode;
 
     /* only bother with an inode for normal files and directories */
-    if (S_ISREG(st.st_mode) || S_ISDIR(st.st_mode))
+    if (S_ISREG(st.st_mode) || S_ISDIR(st.st_mode) || S_ISSOCK(st.st_mode))
     {
         unsigned int err;
         struct inode *inode = get_inode( st.st_dev, st.st_ino, fd->unix_fd );
@@ -2061,7 +2082,10 @@ struct fd *open_fd( struct fd *root, const char *name, struct unicode_str nt_nam
                 set_error( STATUS_OBJECT_NAME_COLLISION );
                 goto error;
             }
-            ftruncate( fd->unix_fd, 0 );
+            if (fd->unix_fd != -1)
+                ftruncate( fd->unix_fd, 0 );
+            else
+                truncate( fd->unix_name, 0 );
         }
     }
     else  /* special file */
-- 
2.50.0

openSUSE Build Service is sponsored by