You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
165 lines
5.5 KiB
165 lines
5.5 KiB
commit 5575daae5099e779bb860b566b4d608418a5b832 |
|
Author: Florian Weimer <fweimer@redhat.com> |
|
Date: Mon Jan 17 10:21:34 2022 +0100 |
|
|
|
socket: Add the __sockaddr_un_set function |
|
|
|
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org> |
|
(cherry picked from commit e368b12f6c16b6888dda99ba641e999b9c9643c8) |
|
|
|
diff --git a/include/sys/un.h b/include/sys/un.h |
|
index bdbee999806930f4..152afd9fc7426d8b 100644 |
|
--- a/include/sys/un.h |
|
+++ b/include/sys/un.h |
|
@@ -1 +1,13 @@ |
|
#include <socket/sys/un.h> |
|
+ |
|
+#ifndef _ISOMAC |
|
+ |
|
+/* Set ADDR->sun_family to AF_UNIX and ADDR->sun_path to PATHNAME. |
|
+ Return 0 on success or -1 on failure (due to overlong PATHNAME). |
|
+ The caller should always use sizeof (struct sockaddr_un) as the |
|
+ socket address length, disregaring the length of PATHNAME. |
|
+ Only concrete (non-abstract) pathnames are supported. */ |
|
+int __sockaddr_un_set (struct sockaddr_un *addr, const char *pathname) |
|
+ attribute_hidden; |
|
+ |
|
+#endif /* _ISOMAC */ |
|
diff --git a/socket/Makefile b/socket/Makefile |
|
index 375957601024c12e..c2de11d73ca1e324 100644 |
|
--- a/socket/Makefile |
|
+++ b/socket/Makefile |
|
@@ -29,13 +29,17 @@ headers := sys/socket.h sys/un.h bits/sockaddr.h bits/socket.h \ |
|
routines := accept bind connect getpeername getsockname getsockopt \ |
|
listen recv recvfrom recvmsg send sendmsg sendto \ |
|
setsockopt shutdown socket socketpair isfdtype opensock \ |
|
- sockatmark accept4 recvmmsg sendmmsg |
|
+ sockatmark accept4 recvmmsg sendmmsg sockaddr_un_set |
|
|
|
tests := \ |
|
tst-accept4 \ |
|
tst-sockopt \ |
|
# tests |
|
|
|
+tests-internal := \ |
|
+ tst-sockaddr_un_set \ |
|
+ # tests-internal |
|
+ |
|
tests-time64 := \ |
|
tst-sockopt-time64 \ |
|
# tests |
|
diff --git a/socket/sockaddr_un_set.c b/socket/sockaddr_un_set.c |
|
new file mode 100644 |
|
index 0000000000000000..0bd40dc34e3d7efc |
|
--- /dev/null |
|
+++ b/socket/sockaddr_un_set.c |
|
@@ -0,0 +1,41 @@ |
|
+/* Set the sun_path member of struct sockaddr_un. |
|
+ Copyright (C) 2022 Free Software Foundation, Inc. |
|
+ This file is part of the GNU C Library. |
|
+ |
|
+ The GNU C Library is free software; you can redistribute it and/or |
|
+ modify it under the terms of the GNU Lesser General Public |
|
+ License as published by the Free Software Foundation; either |
|
+ version 2.1 of the License, or (at your option) any later version. |
|
+ |
|
+ The GNU C Library is distributed in the hope that it will be useful, |
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
+ Lesser General Public License for more details. |
|
+ |
|
+ You should have received a copy of the GNU Lesser General Public |
|
+ License along with the GNU C Library; if not, see |
|
+ <https://www.gnu.org/licenses/>. */ |
|
+ |
|
+#include <errno.h> |
|
+#include <string.h> |
|
+#include <sys/socket.h> |
|
+#include <sys/un.h> |
|
+ |
|
+int |
|
+__sockaddr_un_set (struct sockaddr_un *addr, const char *pathname) |
|
+{ |
|
+ size_t name_length = strlen (pathname); |
|
+ |
|
+ /* The kernel supports names of exactly sizeof (addr->sun_path) |
|
+ bytes, without a null terminator, but userspace does not; see the |
|
+ SUN_LEN macro. */ |
|
+ if (name_length >= sizeof (addr->sun_path)) |
|
+ { |
|
+ __set_errno (EINVAL); /* Error code used by the kernel. */ |
|
+ return -1; |
|
+ } |
|
+ |
|
+ addr->sun_family = AF_UNIX; |
|
+ memcpy (addr->sun_path, pathname, name_length + 1); |
|
+ return 0; |
|
+} |
|
diff --git a/socket/tst-sockaddr_un_set.c b/socket/tst-sockaddr_un_set.c |
|
new file mode 100644 |
|
index 0000000000000000..29c2a81afda81b5e |
|
--- /dev/null |
|
+++ b/socket/tst-sockaddr_un_set.c |
|
@@ -0,0 +1,62 @@ |
|
+/* Test the __sockaddr_un_set function. |
|
+ Copyright (C) 2022 Free Software Foundation, Inc. |
|
+ This file is part of the GNU C Library. |
|
+ |
|
+ The GNU C Library is free software; you can redistribute it and/or |
|
+ modify it under the terms of the GNU Lesser General Public |
|
+ License as published by the Free Software Foundation; either |
|
+ version 2.1 of the License, or (at your option) any later version. |
|
+ |
|
+ The GNU C Library is distributed in the hope that it will be useful, |
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
+ Lesser General Public License for more details. |
|
+ |
|
+ You should have received a copy of the GNU Lesser General Public |
|
+ License along with the GNU C Library; if not, see |
|
+ <https://www.gnu.org/licenses/>. */ |
|
+ |
|
+/* Re-compile the function because the version in libc is not |
|
+ exported. */ |
|
+#include "sockaddr_un_set.c" |
|
+ |
|
+#include <support/check.h> |
|
+ |
|
+static int |
|
+do_test (void) |
|
+{ |
|
+ struct sockaddr_un sun; |
|
+ |
|
+ memset (&sun, 0xcc, sizeof (sun)); |
|
+ __sockaddr_un_set (&sun, ""); |
|
+ TEST_COMPARE (sun.sun_family, AF_UNIX); |
|
+ TEST_COMPARE (__sockaddr_un_set (&sun, ""), 0); |
|
+ |
|
+ memset (&sun, 0xcc, sizeof (sun)); |
|
+ TEST_COMPARE (__sockaddr_un_set (&sun, "/example"), 0); |
|
+ TEST_COMPARE_STRING (sun.sun_path, "/example"); |
|
+ |
|
+ { |
|
+ char pathname[108]; /* Length of sun_path (ABI constant). */ |
|
+ memset (pathname, 'x', sizeof (pathname)); |
|
+ pathname[sizeof (pathname) - 1] = '\0'; |
|
+ memset (&sun, 0xcc, sizeof (sun)); |
|
+ TEST_COMPARE (__sockaddr_un_set (&sun, pathname), 0); |
|
+ TEST_COMPARE (sun.sun_family, AF_UNIX); |
|
+ TEST_COMPARE_STRING (sun.sun_path, pathname); |
|
+ } |
|
+ |
|
+ { |
|
+ char pathname[109]; |
|
+ memset (pathname, 'x', sizeof (pathname)); |
|
+ pathname[sizeof (pathname) - 1] = '\0'; |
|
+ memset (&sun, 0xcc, sizeof (sun)); |
|
+ errno = 0; |
|
+ TEST_COMPARE (__sockaddr_un_set (&sun, pathname), -1); |
|
+ TEST_COMPARE (errno, EINVAL); |
|
+ } |
|
+ |
|
+ return 0; |
|
+} |
|
+ |
|
+#include <support/test-driver.c>
|
|
|