[{"id":3682166,"web_url":"http://patchwork.ozlabs.org/comment/3682166/","msgid":"<de3e0101-185e-4693-ad0e-606e432c75bc@linaro.org>","list_archive_url":null,"date":"2026-04-24T18:32:24","subject":"Re: [PATCH v3] misc: Optimize getusershell.c","submitter":{"id":66065,"url":"http://patchwork.ozlabs.org/api/people/66065/","name":"Adhemerval Zanella Netto","email":"adhemerval.zanella@linaro.org"},"content":"On 24/04/26 14:27, Rocket Ma wrote:\n> * misc/getusershell.c: Completely rewrite the unit. Only allocate one\n> big buffer to store shell names. Add a missing unit test.\n> \n> The new implementation read the whole file into one buffer, and wipe out\n> every byte but shell names. Later when addressing shell names from first\n> shell, jump to next '\\0' and then jump to next '/'. This could reduce\n> memory footprint and shall improve some performance.\n> \n> Signed-off-by: Rocket Ma <marocketbd@gmail.com>\n> ---\n>> I don't think should allow users changing the return value, nor we have this\n>> set in function contract.  Maybe an assert would be better here.\n> \n> The API returns a (char *) without const, so I thought that means the string\n> might be writable then. Anyway, now I assume they are read-only when return.\n\nIndeed, but we historically might return a point to const memory (if the file\ndoes not exist).  I think this is shortcoming from these old Unix interfaces.\n\n> \n>> We try to avoid assignment and comparison in the same expression, we\n>> prefer to:\n> \n> I referred some glibc code and add a comment, now the code should be neater.\n> \n>> The current implementation already sets and returns read-only strings,\n>> so the implicit function contract is user are not supposed to write on\n>> the getusershell returned values.  So I think there is no much gain in\n>> returning allocated strings here.\n> \n> OK, directly point shells to builtin ones when fail.\n> \n>> Missing space before '(' here and below.\n> \n> I forgot to run clang-format when finishing the test. :)\n> \n> Note: you are reviewing my patch v1, not v2.\n\nOops, I have this on my backlog and I forgot to check on v2.\n\nThis version looks ok to me, thanks.\n\nReviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>\n\n> ---\n>  misc/Makefile                |   1 +\n>  misc/getusershell.c          | 265 ++++++++++++++++++-----------------\n>  misc/tst-getusershell.c      |  75 ++++++++++\n>  misc/tst-getusershell.shells |   7 +\n>  4 files changed, 223 insertions(+), 125 deletions(-)\n>  create mode 100644 misc/tst-getusershell.c\n>  create mode 100644 misc/tst-getusershell.shells\n> \n> diff --git a/misc/Makefile b/misc/Makefile\n> index 4395366d74..31c930ef64 100644\n> --- a/misc/Makefile\n> +++ b/misc/Makefile\n> @@ -245,6 +245,7 @@ tests := \\\n>    tst-empty \\\n>    tst-error1 \\\n>    tst-fdset \\\n> +  tst-getusershell \\\n>    tst-hsearch \\\n>    tst-insremque \\\n>    tst-ioctl \\\n> diff --git a/misc/getusershell.c b/misc/getusershell.c\n> index 4221095dca..e30c566f9d 100644\n> --- a/misc/getusershell.c\n> +++ b/misc/getusershell.c\n> @@ -1,143 +1,158 @@\n> -/*\n> - * Copyright (c) 1985, 1993\n> - *\tThe Regents of the University of California.  All rights reserved.\n> - *\n> - * Redistribution and use in source and binary forms, with or without\n> - * modification, are permitted provided that the following conditions\n> - * are met:\n> - * 1. Redistributions of source code must retain the above copyright\n> - *    notice, this list of conditions and the following disclaimer.\n> - * 2. Redistributions in binary form must reproduce the above copyright\n> - *    notice, this list of conditions and the following disclaimer in the\n> - *    documentation and/or other materials provided with the distribution.\n> - * 4. Neither the name of the University nor the names of its contributors\n> - *    may be used to endorse or promote products derived from this software\n> - *    without specific prior written permission.\n> - *\n> - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n> - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n> - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n> - * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n> - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n> - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n> - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n> - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n> - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n> - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n> - * SUCH DAMAGE.\n> - */\n> -\n> -#if defined(LIBC_SCCS) && !defined(lint)\n> -static char sccsid[] = \"@(#)getusershell.c\t8.1 (Berkeley) 6/4/93\";\n> -#endif /* LIBC_SCCS and not lint */\n> -\n> -#include <sys/param.h>\n> -#include <sys/file.h>\n> -#include <sys/stat.h>\n> +/* Copyright (C) 2026 The GNU Toolchain Authors.\n> +   This file is part of the GNU C Library.\n> +\n> +   The GNU C Library is free software; you can redistribute it and/or\n> +   modify it under the terms of the GNU Lesser General Public\n> +   License as published by the Free Software Foundation; either\n> +   version 2.1 of the License, or (at your option) any later version.\n> +\n> +   The GNU C Library is distributed in the hope that it will be useful,\n> +   but WITHOUT ANY WARRANTY; without even the implied warranty of\n> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n> +   Lesser General Public License for more details.\n> +\n> +   You should have received a copy of the GNU Lesser General Public\n> +   License along with the GNU C Library; if not, see\n> +   <https://www.gnu.org/licenses/>.  */\n> +\n> +#include \"ctype/ctype.h\"\n> +#include \"iolibio.h\"\n> +#include <assert.h>\n> +#include <fcntl.h>\n> +#include <stddef.h>\n>  #include <stdio.h>\n> -#include <stdio_ext.h>\n> -#include <ctype.h>\n> -#include <stdlib.h>\n> +#include <stdint.h>\n> +#include <sys/stat.h>\n>  #include <unistd.h>\n>  #include <paths.h>\n> +#include <stdlib.h>\n> +#include <string.h>\n>  \n> -/*\n> - * Local shells should NOT be added here.  They should be added in\n> - * /etc/shells.\n> - */\n> -\n> -/* NB: we do not initialize okshells here.  The initialization needs\n> -   relocations.  These interfaces are used so rarely that this is not\n> -   justified.  Instead explicitly initialize the array when it is\n> -   used.  */\n> -#if 0\n> -static const char *const okshells[] = { _PATH_BSHELL, _PATH_CSHELL, NULL };\n> -#else\n> -static const char *okshells[3];\n> -#endif\n> -static char **curshell, **shells, *strings;\n> -static char **initshells (void) __THROW;\n> -\n> -/*\n> - * Get a list of shells from _PATH_SHELLS, if it exists.\n> - */\n> -char *\n> -getusershell (void)\n> +#define DEFAULT_SHELLS _PATH_BSHELL \"\\0\" _PATH_CSHELL\n> +\n> +static char *shellbuf;\n> +static char *shellend;\n> +static char *nextshell;\n> +\n> +static char *\n> +address_next_shell (void)\n>  {\n> -\tchar *ret;\n> -\n> -\tif (curshell == NULL)\n> -\t\tcurshell = initshells();\n> -\tret = *curshell;\n> -\tif (ret != NULL)\n> -\t\tcurshell++;\n> -\treturn (ret);\n> +  char *curshell = nextshell;\n> +  if (nextshell == NULL)\n> +    return curshell;\n> +\n> +  /* init_shells guarantees we have a \\0 at the end */\n> +  char *next0 = memchr (nextshell, '\\0', shellend - nextshell);\n> +  assert (next0 != NULL);\n> +  nextshell = memchr (next0, '/', shellend - next0);\n> +  return curshell;\n>  }\n>  \n> -void\n> -endusershell (void)\n> +/* Read /etc/shells, strip unnecessary bytes, and setup nextshell */\n> +static void\n> +init_shells (void)\n>  {\n> +  free (shellbuf);\n> +  shellbuf = NULL;\n> +  shellend = NULL;\n> +  nextshell = NULL;\n> +\n> +  struct __stat64_t64 fstat;\n> +  FILE *fp = fopen (_PATH_SHELLS, \"rce\");\n> +  if (fp == NULL)\n> +    goto default_out;\n> +  int rc = __fstat64_time64 (__fileno (fp), &fstat);\n> +  if (rc == -1)\n> +    goto close_out;\n> +  /* Consider if buflen will overflow. */\n> +  if (fstat.st_size < 2 || fstat.st_size > PTRDIFF_MAX - 1)\n> +    goto close_out;\n> +  /* 1 byte for \\n (will be overwritten as \\0). */\n> +  size_t buflen = fstat.st_size + 1;\n> +  shellbuf = malloc (buflen);\n> +  if (shellbuf == NULL)\n> +    goto close_out;\n> +  shellbuf[buflen - 1] = '\\n';\n> +  _IO_setbuf (fp, NULL);\n> +  size_t cnt = _IO_fread (shellbuf, 1, fstat.st_size, fp);\n> +  if (cnt != fstat.st_size)\n> +    goto free_out;\n>  \n> -\tfree(shells);\n> -\tshells = NULL;\n> -\tfree(strings);\n> -\tstrings = NULL;\n> -\tcurshell = NULL;\n> +  /* Loop through file and only keep shell names.\n> +     The rest characters are set to \\0 to reduce addressing workload. */\n> +  char *top;\n> +  char *line_start, *line_end;\n> +  char *slash, *discard;\n> +\n> +  top = shellbuf + buflen;\n> +  line_start = shellbuf;\n> +  while ((line_end = memchr (line_start, '\\n', top - line_start)) != NULL)\n> +    {\n> +      line_end++; /* include \\n */\n> +      discard = line_start;\n> +\n> +      slash = memchr (line_start, '/', line_end - line_start);\n> +      if (slash == NULL)\n> +\tgoto wipe_line;\n> +\n> +      discard = memchr (line_start, '#', line_end - line_start);\n> +      if (discard != NULL && discard < slash)\n> +\tgoto wipe_line;\n> +\n> +      (void) memset (line_start, '\\0', slash - line_start);\n> +      discard = slash;\n> +      while (discard < line_end && *discard != '#'\n> +\t     && !isspace_l ((unsigned char) *discard, _nl_C_locobj_ptr))\n> +\tdiscard++;\n> +\n> +    wipe_line:\n> +      (void) memset (discard, '\\0', line_end - discard);\n> +      line_start = line_end;\n> +    }\n> +\n> +  nextshell = memchr (shellbuf, '/', top - shellbuf);\n> +  if (nextshell == NULL)\n> +    goto free_out;\n> +  shellend = top;\n> +  (void) fclose (fp);\n> +  return;\n> +\n> +free_out:\n> +  free (shellbuf);\n> +  shellbuf = NULL;\n> +close_out:\n> +  (void) fclose (fp);\n> +default_out:\n> +  /* Fallback plan: use builtin read-only default shells.\n> +     shellbuf is NULL here so it can be freed.*/\n> +  nextshell = (char *) DEFAULT_SHELLS;\n> +  shellend = (char *) DEFAULT_SHELLS + sizeof (DEFAULT_SHELLS);\n> +}\n> +\n> +char *\n> +getusershell (void)\n> +{\n> +  if (shellend == NULL)\n> +    init_shells ();\n> +  return address_next_shell ();\n>  }\n>  \n>  void\n>  setusershell (void)\n>  {\n> -\n> -\tcurshell = initshells();\n> +  if (shellend == NULL)\n> +    init_shells ();\n> +  else if (shellbuf != NULL)\n> +    nextshell = memchr (shellbuf, '/', shellend - shellbuf);\n> +  else /* shellend != NULL && shellbuf == NULL */\n> +    nextshell = (char *) DEFAULT_SHELLS;\n>  }\n>  \n> -static char **\n> -initshells (void)\n> +void\n> +endusershell (void)\n>  {\n> -\tchar **sp, *cp;\n> -\tFILE *fp;\n> -\tstruct __stat64_t64 statb;\n> -\tsize_t flen;\n> -\n> -\tfree(shells);\n> -\tshells = NULL;\n> -\tfree(strings);\n> -\tstrings = NULL;\n> -\tif ((fp = fopen(_PATH_SHELLS, \"rce\")) == NULL)\n> -\t\tgoto init_okshells_noclose;\n> -\tif (__fstat64_time64(fileno(fp), &statb) == -1) {\n> -\tinit_okshells:\n> -\t\t(void)fclose(fp);\n> -\tinit_okshells_noclose:\n> -\t\tokshells[0] = _PATH_BSHELL;\n> -\t\tokshells[1] = _PATH_CSHELL;\n> -\t\treturn (char **) okshells;\n> -\t}\n> -\tif (statb.st_size > ~(size_t)0 / sizeof (char *) * 3)\n> -\t\tgoto init_okshells;\n> -\tflen = statb.st_size + 3;\n> -\tif ((strings = malloc(flen)) == NULL)\n> -\t\tgoto init_okshells;\n> -\tshells = malloc(statb.st_size / 3 * sizeof (char *));\n> -\tif (shells == NULL) {\n> -\t\tfree(strings);\n> -\t\tstrings = NULL;\n> -\t\tgoto init_okshells;\n> -\t}\n> -\tsp = shells;\n> -\tcp = strings;\n> -\twhile (fgets_unlocked(cp, flen - (cp - strings), fp) != NULL) {\n> -\t\twhile (*cp != '#' && *cp != '/' && *cp != '\\0')\n> -\t\t\tcp++;\n> -\t\tif (*cp == '#' || *cp == '\\0' || cp[1] == '\\0')\n> -\t\t\tcontinue;\n> -\t\t*sp++ = cp;\n> -\t\twhile (!isspace(*cp) && *cp != '#' && *cp != '\\0')\n> -\t\t\tcp++;\n> -\t\t*cp++ = '\\0';\n> -\t}\n> -\t*sp = NULL;\n> -\t(void)fclose(fp);\n> -\treturn (shells);\n> +  free (shellbuf);\n> +  shellbuf = NULL;\n> +  shellend = NULL;\n> +  nextshell = NULL;\n>  }\n> diff --git a/misc/tst-getusershell.c b/misc/tst-getusershell.c\n> new file mode 100644\n> index 0000000000..e60cabce3a\n> --- /dev/null\n> +++ b/misc/tst-getusershell.c\n> @@ -0,0 +1,75 @@\n> +/* Test the getusershell series functions.\n> +   Copyright (C) 2026 The GNU Toolchain Authors.\n> +   This file is part of the GNU C Library.\n> +\n> +   The GNU C Library is free software; you can redistribute it and/or\n> +   modify it under the terms of the GNU Lesser General Public\n> +   License as published by the Free Software Foundation; either\n> +   version 2.1 of the License, or (at your option) any later version.\n> +\n> +   The GNU C Library is distributed in the hope that it will be useful,\n> +   but WITHOUT ANY WARRANTY; without even the implied warranty of\n> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n> +   Lesser General Public License for more details.\n> +\n> +   You should have received a copy of the GNU Lesser General Public\n> +   License along with the GNU C Library; if not, see\n> +   <https://www.gnu.org/licenses/>.  */\n> +\n> +#include \"support/temp_file.h\"\n> +#include <stdlib.h>\n> +#include <unistd.h>\n> +#include <paths.h>\n> +#include <support/check.h>\n> +#include <support/xunistd.h>\n> +#include <support/support.h>\n> +#include <support/namespace.h>\n> +#include <support/test-driver.h>\n> +\n> +static void\n> +test_in_chroot (void *chroot_path)\n> +{\n> +  xchroot (chroot_path);\n> +\n> +  TEST_COMPARE_STRING (getusershell (), \"/bin/sh\");\n> +  TEST_COMPARE_STRING (getusershell (), \"/bin/bash\");\n> +  TEST_COMPARE_STRING (getusershell (), \"/usr/bin/zsh\");\n> +  TEST_COMPARE_STRING (getusershell (), NULL);\n> +  TEST_COMPARE_STRING (getusershell (), NULL);\n> +\n> +  setusershell ();\n> +  TEST_COMPARE_STRING (getusershell (), \"/bin/sh\");\n> +  endusershell ();\n> +\n> +  xunlink (\"/etc/shells\");\n> +  TEST_COMPARE_STRING (getusershell (), \"/bin/sh\");\n> +  TEST_COMPARE_STRING (getusershell (), \"/bin/csh\");\n> +  TEST_COMPARE_STRING (getusershell (), NULL);\n> +  endusershell ();\n> +}\n> +\n> +static int\n> +do_test (void)\n> +{\n> +  support_become_root ();\n> +  if (!support_can_chroot ())\n> +    return EXIT_UNSUPPORTED;\n> +\n> +  char *chroot_dir = support_create_temp_directory (\"tst-getusershell-\");\n> +  char *etc = xasprintf (\"%s/etc\", chroot_dir);\n> +  add_temp_file (etc);\n> +  xmkdir (etc, 0777);\n> +  /* Don't add shells to file list as it will be deleted in test. */\n> +  char *shells = xasprintf (\"%s/shells\", etc);\n> +  support_copy_file (\"tst-getusershell.shells\", shells);\n> +\n> +  support_isolate_in_subprocess (test_in_chroot, chroot_dir);\n> +\n> +  free (etc);\n> +  free (shells);\n> +  free (chroot_dir);\n> +\n> +  return 0;\n> +}\n> +\n> +#include <support/test-driver.c>\n> diff --git a/misc/tst-getusershell.shells b/misc/tst-getusershell.shells\n> new file mode 100644\n> index 0000000000..fcc7675398\n> --- /dev/null\n> +++ b/misc/tst-getusershell.shells\n> @@ -0,0 +1,7 @@\n> +# test hash\n> +  # indentation\n> +\n> +/bin/sh\n> +\t/bin/bash # ...\n> +\n> +xx /usr/bin/zsh#...\n> \\ No newline at end of file","headers":{"Return-Path":"<libc-alpha-bounces~incoming=patchwork.ozlabs.org@sourceware.org>","X-Original-To":["incoming@patchwork.ozlabs.org","libc-alpha@sourceware.org"],"Delivered-To":["patchwork-incoming@legolas.ozlabs.org","libc-alpha@sourceware.org"],"Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256\n header.s=google header.b=Rs6ETBHw;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org\n (client-ip=2620:52:6:3111::32; helo=vm01.sourceware.org;\n envelope-from=libc-alpha-bounces~incoming=patchwork.ozlabs.org@sourceware.org;\n receiver=patchwork.ozlabs.org)","sourceware.org;\n\tdkim=pass (2048-bit key,\n unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256\n header.s=google header.b=Rs6ETBHw","sourceware.org;\n dmarc=pass (p=none dis=none) header.from=linaro.org","sourceware.org; spf=pass smtp.mailfrom=linaro.org","server2.sourceware.org;\n arc=none smtp.remote-ip=2607:f8b0:4864:20::132f"],"Received":["from vm01.sourceware.org (vm01.sourceware.org\n [IPv6:2620:52:6:3111::32])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g2M5h2ZjBz1yD5\n\tfor <incoming@patchwork.ozlabs.org>; Sat, 25 Apr 2026 04:32:56 +1000 (AEST)","from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id 5D81B4B920C7\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 24 Apr 2026 18:32:54 +0000 (GMT)","from mail-dy1-x132f.google.com (mail-dy1-x132f.google.com\n [IPv6:2607:f8b0:4864:20::132f])\n by sourceware.org (Postfix) with ESMTPS id C47024B99F5B\n for <libc-alpha@sourceware.org>; Fri, 24 Apr 2026 18:32:29 +0000 (GMT)","by mail-dy1-x132f.google.com with SMTP id\n 5a478bee46e88-2d832f2f44cso7157337eec.0\n for <libc-alpha@sourceware.org>; Fri, 24 Apr 2026 11:32:29 -0700 (PDT)","from ?IPV6:2804:1b3:a7c0:44cb:cca5:e86f:f029:1073?\n ([2804:1b3:a7c0:44cb:cca5:e86f:f029:1073])\n by smtp.gmail.com with ESMTPSA id\n a92af1059eb24-12c74a20eb5sm42153988c88.14.2026.04.24.11.32.26\n (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128);\n Fri, 24 Apr 2026 11:32:27 -0700 (PDT)"],"DKIM-Filter":["OpenDKIM Filter v2.11.0 sourceware.org 5D81B4B920C7","OpenDKIM Filter v2.11.0 sourceware.org C47024B99F5B"],"DMARC-Filter":"OpenDMARC Filter v1.4.2 sourceware.org C47024B99F5B","ARC-Filter":"OpenARC Filter v1.0.0 sourceware.org C47024B99F5B","ARC-Seal":"i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1777055550; cv=none;\n b=Of0evuA/J7ewsgERmZ+1AEtC8vnpfpK5L+rQHexz6ILAbCHWgeNOmz0oAz36u0/5NeDVENua+/witdvmJkyxGFvb52BYMHckvytqEBoaQ3Oup7rhBb3B2eY+XRFg6+5u3E6kaKoKUUFf2tDhRVeoWQZl8sVBg79gm3sjd9IlVqw=","ARC-Message-Signature":"i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1777055550; c=relaxed/simple;\n bh=uPF0J26qXdMh4yGvdKFPE6ouwW5fef5pVy4STCcIbpE=;\n h=DKIM-Signature:Message-ID:Date:MIME-Version:Subject:To:From;\n b=kVEYJ6O/InDA8J29itjo59C0jXp1lJC4u19blZNnbR28RHA5EfW9L5RJTQ9FgOvwxTG1F8DhOdKpMfbVZ9/ypkU/FUAeHdiOOdBU9aS+5zakIJhOTPz18KQRwm8kOtF6duqLngQuVZ1OzbV7AnmyDhbJCEo5jM/DE4BpaOlrTWU=","ARC-Authentication-Results":"i=1; server2.sourceware.org","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=linaro.org; s=google; t=1777055549; x=1777660349; darn=sourceware.org;\n h=content-transfer-encoding:in-reply-to:organization:from\n :content-language:references:cc:to:subject:user-agent:mime-version\n :date:message-id:from:to:cc:subject:date:message-id:reply-to;\n bh=3AL68xO2haLGPpa2vc+Tuesd6aAFtIn94wgvzQVXhjA=;\n b=Rs6ETBHwXVH0nxhBr1cOxECnTVkMhPlBZE5OqYYNvLXVT+ReKwFyJ2Ofp/Oqim7fzU\n Qx9tYOIIEyBViMtDmzjlHtzVNL00tFakPb6JegsO6kq2qffkGSRKC82rDdvkW+PEo0mF\n 2saYltOggGJfA3S6Da/wn/FaaAinx4HhDsaheIaBB9hTkCMRcdEFLtIEGLYuCupURKJb\n /cLzgxja2BhMbLhxC1wvw6/TXjk1rIWfUs0Pm1JKp6Fya4JkPCbgN2X4YGX48e2pZ/1N\n RK/V6CtlrY9f18BI0+vePzoLthOCPAFnD4fCYLtGr7f3mE2BfRc5rjvkPmb/cKTlGx3h\n DHsQ==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1777055549; x=1777660349;\n h=content-transfer-encoding:in-reply-to:organization:from\n :content-language:references:cc:to:subject:user-agent:mime-version\n :date:message-id:x-gm-gg:x-gm-message-state:from:to:cc:subject:date\n :message-id:reply-to;\n bh=3AL68xO2haLGPpa2vc+Tuesd6aAFtIn94wgvzQVXhjA=;\n b=cMmzcpQs9KNa4NqaBBBft6SJxHqwJ6K63DgWzr0qhMAk5176ZeHMFBQoXOCxcz4USk\n prWQhNLa+IKQCzADX1CA2GpgkpTTQtz2QLiRgcx7UwqpVt6roGpAyPpgw9KIpnYqMbAS\n FJIk+yOBf5MBVwCKT8061BZyuYCKV5+GRe7qwdmLCeMWMhX8FTBI++b6/Ar8KYHoSwAl\n UvTfMJZRCwI9j0JuMck+zVItOmODGE1Dj5Ld8LpFeQ7XmjyVAy1BDa1EyQds3YCkej6C\n +6M/ej5QPEERJhqQJAgTy1ekd+5uEdu/aAPCSdUY1TG/1uZAi2+HAzK06N3+UrBR+yCL\n tfuw==","X-Gm-Message-State":"AOJu0YymFr2+gvCDw6iJ4c0dNgFyK4iyUwgncs3UOEZpTIL3fint29ZM\n SgpMQ7JIdFB5Uvur49cPZnuwctqwg4Wen9ktEueGWyLvKHxx8XbImBRlMHa2vUu15bzr9ih98z4\n Jslfj","X-Gm-Gg":"AeBDieuEurOCUR+QEosmfD07SV0vLm31WLVKnT+zs3VTfgQorifTNog5Kz/Tf0f/Zya\n EFRJwn93HMfrX+f9ztre6KV/XAfS+lCundURK+3N5gp7gd6thOBYzC+OFq+Dgy64oopkSUZqCb4\n mzYmPj7nOOBMv0UxJsjZhNH43TzhHKnUL/lRXFFx3xlOaQJpjOkK1bZfCZ6BVl2TiuO2Xx+LKmA\n uUQDKRExSgQcObCfDcNXDXHfTebk6GdQAanVTMq078gbrZ3qZCkxLDVlcRCxnae1Z3pKVOrBMkv\n CRqQLH4YTb1s/N3qBXGnr4Db3zS9o9s5OydCCKoEVVRPoy+MUcF4oWLq0E5w8vwkG74eWmf2rhW\n EjbT+rLbg6B5wmphlrwW07ke9JBMkEjO6iHRWHjp8hqmoEL3lKxZgw0XaCs3XINo368c1NGJPSV\n rHipvr/5znXU3oJIHSaOKUjgdeG6lmSTZCIlICz52TWj1HeN/9V0YoF1troM7mk6LOLIY8eqQPH\n Cn+MJvnyYfCFXbggVOrT4L1zIgs8ldq5oRFDsT5grNN","X-Received":"by 2002:a05:7022:fe04:b0:12d:b175:2573 with SMTP id\n a92af1059eb24-12db17526edmr9922251c88.7.1777055548097;\n Fri, 24 Apr 2026 11:32:28 -0700 (PDT)","Message-ID":"<de3e0101-185e-4693-ad0e-606e432c75bc@linaro.org>","Date":"Fri, 24 Apr 2026 15:32:24 -0300","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH v3] misc: Optimize getusershell.c","To":"Rocket Ma <marocketbd@gmail.com>","Cc":"libc-alpha@sourceware.org, Collin Funk <collin.funk1@gmail.com>","References":"<20260422164926.62177-1-marocketbd@gmail.com>\n <20260424172759.212189-1-marocketbd@gmail.com>","Content-Language":"en-US","From":"Adhemerval Zanella Netto <adhemerval.zanella@linaro.org>","Organization":"Linaro","In-Reply-To":"<20260424172759.212189-1-marocketbd@gmail.com>","Content-Type":"text/plain; charset=UTF-8","Content-Transfer-Encoding":"7bit","X-BeenThere":"libc-alpha@sourceware.org","X-Mailman-Version":"2.1.30","Precedence":"list","List-Id":"Libc-alpha mailing list <libc-alpha.sourceware.org>","List-Unsubscribe":"<https://sourceware.org/mailman/options/libc-alpha>,\n <mailto:libc-alpha-request@sourceware.org?subject=unsubscribe>","List-Archive":"<https://sourceware.org/pipermail/libc-alpha/>","List-Post":"<mailto:libc-alpha@sourceware.org>","List-Help":"<mailto:libc-alpha-request@sourceware.org?subject=help>","List-Subscribe":"<https://sourceware.org/mailman/listinfo/libc-alpha>,\n <mailto:libc-alpha-request@sourceware.org?subject=subscribe>","Errors-To":"libc-alpha-bounces~incoming=patchwork.ozlabs.org@sourceware.org"}}]