From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1804) id 2D5AE382F987; Fri, 7 Oct 2022 08:20:38 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 2D5AE382F987 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1665130838; bh=04TjzRr6ViCoObbtZqe4GuHComwJSU855RzKr67OryE=; h=From:To:Subject:Date:From; b=GJv6jza1k6ZTCgrv86/3WamJpYAsojfaAOTfA2dEtGnkErC22TfypkVt1rh60BwVL PIabcSOwfHrcVgBU9+Bn2fmndu5LOFUmAK/5Es7eyCWEpu8cng0hp/8e5UxelAqzqc s8iFR/21YzhUwa3REwAHHmzhgCdWHSlVv2VGlPt8= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Dmitry Levin To: glibc-cvs@sourceware.org Subject: [glibc/release/2.32/master] socket: Add the __sockaddr_un_set function X-Act-Checkin: glibc X-Git-Author: Florian Weimer X-Git-Refname: refs/heads/release/2.32/master X-Git-Oldrev: 6fd634e9b922a4a1293f0cf5a8f6c908f68c5401 X-Git-Newrev: b10d5e62a6ac7688305772eb64aac3eda87b1623 Message-Id: <20221007082038.2D5AE382F987@sourceware.org> Date: Fri, 7 Oct 2022 08:20:38 +0000 (GMT) List-Id: https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=b10d5e62a6ac7688305772eb64aac3eda87b1623 commit b10d5e62a6ac7688305772eb64aac3eda87b1623 Author: Florian Weimer Date: Mon Jan 17 10:21:34 2022 +0100 socket: Add the __sockaddr_un_set function Reviewed-by: Siddhesh Poyarekar (cherry picked from commit e368b12f6c16b6888dda99ba641e999b9c9643c8) Diff: --- include/sys/un.h | 12 +++++++++ socket/Makefile | 6 ++++- socket/sockaddr_un_set.c | 41 +++++++++++++++++++++++++++++ socket/tst-sockaddr_un_set.c | 62 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 120 insertions(+), 1 deletion(-) diff --git a/include/sys/un.h b/include/sys/un.h index bdbee99980..152afd9fc7 100644 --- a/include/sys/un.h +++ b/include/sys/un.h @@ -1 +1,13 @@ #include + +#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 125c042cab..19fc6ab41d 100644 --- a/socket/Makefile +++ b/socket/Makefile @@ -29,10 +29,14 @@ 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 +tests-internal := \ + tst-sockaddr_un_set \ + # tests-internal + aux := sa_len include ../Rules diff --git a/socket/sockaddr_un_set.c b/socket/sockaddr_un_set.c new file mode 100644 index 0000000000..0bd40dc34e --- /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 + . */ + +#include +#include +#include +#include + +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 0000000000..29c2a81afd --- /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 + . */ + +/* Re-compile the function because the version in libc is not + exported. */ +#include "sockaddr_un_set.c" + +#include + +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