aboutsummaryrefslogtreecommitdiff
path: root/socket
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2022-01-17 10:21:34 +0100
committerFlorian Weimer <fweimer@redhat.com>2022-01-17 11:44:41 +0100
commit5575daae5099e779bb860b566b4d608418a5b832 (patch)
tree3bc5ef6c685e1f042082f98ef522a879b87a21ca /socket
parent03e6e02e6a216cfb913f49b3be80d5088603864f (diff)
downloadglibc-5575daae5099e779bb860b566b4d608418a5b832.zip
glibc-5575daae5099e779bb860b566b4d608418a5b832.tar.gz
glibc-5575daae5099e779bb860b566b4d608418a5b832.tar.bz2
socket: Add the __sockaddr_un_set function
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org> (cherry picked from commit e368b12f6c16b6888dda99ba641e999b9c9643c8)
Diffstat (limited to 'socket')
-rw-r--r--socket/Makefile6
-rw-r--r--socket/sockaddr_un_set.c41
-rw-r--r--socket/tst-sockaddr_un_set.c62
3 files changed, 108 insertions, 1 deletions
diff --git a/socket/Makefile b/socket/Makefile
index 3759576..c2de11d 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 0000000..0bd40dc
--- /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 0000000..29c2a81
--- /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>