get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/1.2/patches/2224690/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 2224690,
    "url": "http://patchwork.ozlabs.org/api/1.2/patches/2224690/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/glibc/patch/fd9039a2989834a76986db9d59b8b3e5fe81f595.1776449736.git.dj@redhat.com/",
    "project": {
        "id": 41,
        "url": "http://patchwork.ozlabs.org/api/1.2/projects/41/?format=api",
        "name": "GNU C Library",
        "link_name": "glibc",
        "list_id": "libc-alpha.sourceware.org",
        "list_email": "libc-alpha@sourceware.org",
        "web_url": "",
        "scm_url": "",
        "webscm_url": "",
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<fd9039a2989834a76986db9d59b8b3e5fe81f595.1776449736.git.dj@redhat.com>",
    "list_archive_url": null,
    "date": "2026-02-11T04:33:51",
    "name": "[v7,4/4] Add system-wide tunables: Filters",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "e1ea386ea0061bd7f1b78ff5378146f4111ac50b",
    "submitter": {
        "id": 4388,
        "url": "http://patchwork.ozlabs.org/api/1.2/people/4388/?format=api",
        "name": "DJ Delorie",
        "email": "dj@redhat.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/glibc/patch/fd9039a2989834a76986db9d59b8b3e5fe81f595.1776449736.git.dj@redhat.com/mbox/",
    "series": [
        {
            "id": 500385,
            "url": "http://patchwork.ozlabs.org/api/1.2/series/500385/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/glibc/list/?series=500385",
            "date": "2024-02-21T23:49:50",
            "name": "Add system-wide tunables",
            "version": 7,
            "mbox": "http://patchwork.ozlabs.org/series/500385/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2224690/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2224690/checks/",
    "tags": {},
    "related": [],
    "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 (1024-bit key;\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=Ye6mNpfT;\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 (1024-bit key,\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=Ye6mNpfT",
            "sourceware.org; dmarc=pass (p=quarantine dis=none)\n header.from=redhat.com",
            "sourceware.org; spf=pass smtp.mailfrom=redhat.com",
            "server2.sourceware.org;\n arc=none smtp.remote-ip=170.10.133.124"
        ],
        "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 4fy38H4XHcz1yDF\n\tfor <incoming@patchwork.ozlabs.org>; Sat, 18 Apr 2026 04:20:15 +1000 (AEST)",
            "from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id 95CD74CCCA07\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 17 Apr 2026 18:20:13 +0000 (GMT)",
            "from us-smtp-delivery-124.mimecast.com\n (us-smtp-delivery-124.mimecast.com [170.10.133.124])\n by sourceware.org (Postfix) with ESMTP id C23A14AA3972\n for <libc-alpha@sourceware.org>; Fri, 17 Apr 2026 18:18:38 +0000 (GMT)",
            "from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com\n (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by\n relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3,\n cipher=TLS_AES_256_GCM_SHA384) id us-mta-660-sce74b0rOFybXipvlYi9HQ-1; Fri,\n 17 Apr 2026 14:18:37 -0400",
            "from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com\n (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest\n SHA256)\n (No client certificate requested)\n by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS\n id 4D831195608B\n for <libc-alpha@sourceware.org>; Fri, 17 Apr 2026 18:18:36 +0000 (UTC)",
            "from greed.delorie.com (unknown [10.22.88.82])\n by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with\n ESMTPS\n id 0A62919560AB\n for <libc-alpha@sourceware.org>; Fri, 17 Apr 2026 18:18:35 +0000 (UTC)",
            "from greed.delorie.com (localhost [127.0.0.1])\n by greed.delorie.com (8.16.1/8.16.1) with ESMTPS id 63HIIYIk652002\n (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT)\n for <libc-alpha@sourceware.org>; Fri, 17 Apr 2026 14:18:34 -0400",
            "(from dj@localhost)\n by greed.delorie.com (8.16.1/8.16.1/Submit) id 63HIIYGM652001;\n Fri, 17 Apr 2026 14:18:34 -0400"
        ],
        "DKIM-Filter": [
            "OpenDKIM Filter v2.11.0 sourceware.org 95CD74CCCA07",
            "OpenDKIM Filter v2.11.0 sourceware.org C23A14AA3972"
        ],
        "DMARC-Filter": "OpenDMARC Filter v1.4.2 sourceware.org C23A14AA3972",
        "ARC-Filter": "OpenARC Filter v1.0.0 sourceware.org C23A14AA3972",
        "ARC-Seal": "i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1776449918; cv=none;\n b=o6jX3Nmh4Jhch+9dgdZ7k0FjeKe6GF/1F+4tXjX4v3XAe35jE8vnT3uXrnglMF2GTR5xAydKNNL02k4iRw8dF76K1JzLvhWiWMHEXSCk5imVJyOBl4XjOGW9PG5TBloUJ+RMod2U+9QC2rEahfbOMJhbSLTLE+FPuBbtEz7Hj+s=",
        "ARC-Message-Signature": "i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1776449918; c=relaxed/simple;\n bh=W2qjt4VafldKEe2bAIQNTWOl4pPRRWsmTqpAkPVSjUY=;\n h=DKIM-Signature:Message-ID:From:Date:Subject:To;\n b=f/kc/ZoxjG/GATsuSBo9FbfOqGjB1hfJ+jm82YHry0WFtNhCQ7uO1sc/Fk8U7iP0Oc2Mq24kkpCxhRZaU1SzpWOHWe8FE3qsHHRJFPQh4/FSsLEpA9FPSktokEUNUVCamgcVKtZUASQ75OanVDwS7D0XyUZl1KLRloBBY6Wsu5c=",
        "ARC-Authentication-Results": "i=1; server2.sourceware.org",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n s=mimecast20190719; t=1776449918;\n h=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n to:to:cc:content-type:content-type:in-reply-to:in-reply-to:\n references:references; bh=uumg9HduLzBZGncgNTGciAp5WtLgGUHIN1HJfkyKabI=;\n b=Ye6mNpfTU0Mn7ZPGA1BmzAvkGrZuBeaUKaSPRku4qYpF1cpSm3kj459ta7j1tOBH7jwPsG\n 0T4MjkQoWHBdfnfUEpE33SWFHDa23SwDRpnTfLN2sN+U44eVVHo9PThZQixLNAaBjHuFy4\n G75G+ECmubY6QUtboobWt5uqBu1zj4k=",
        "X-MC-Unique": "sce74b0rOFybXipvlYi9HQ-1",
        "X-Mimecast-MFC-AGG-ID": "sce74b0rOFybXipvlYi9HQ_1776449916",
        "Message-ID": "\n <fd9039a2989834a76986db9d59b8b3e5fe81f595.1776449736.git.dj@redhat.com>",
        "In-Reply-To": "<cover.1776449736.git.dj@redhat.com>",
        "References": "<cover.1776449736.git.dj@redhat.com>",
        "From": "DJ Delorie <dj@redhat.com>",
        "Date": "Tue, 10 Feb 2026 23:33:51 -0500",
        "Subject": "[PATCH v7 4/4] Add system-wide tunables: Filters",
        "To": "libc-alpha@sourceware.org",
        "X-Scanned-By": "MIMEDefang 3.0 on 10.30.177.17",
        "X-Mimecast-Spam-Score": "2",
        "X-Mimecast-MFC-PROC-ID": "Xj0xnX4uqoY0qWPcKYt2zR7Od5EsiHLkiuZv_1c8WKg_1776449916",
        "X-Mimecast-Originator": "redhat.com",
        "Content-type": "text/plain; charset=UTF-8",
        "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"
    },
    "content": "Add support for [proc:*] syntax where * matches /proc/self/exe\n(fallback: argv[0] unless AT_SECURE).  Tunables after such a\nline are limited to matching processes.\n\nNote that this filter is reset when including a file or at\nend of file.\n\nIf the filename starts with a slash (example: [proc:/bin/foo]) the\nfull path must match.  If not (example: [proc:foo]) the basename is\nmatched.\n\nAdd support for filtering out AT_SECURE or non-AT_SECURE binaries:\n\n  $glibc.only-for.unsecure-binaries=1\n  @glibc.only-for.secure-binaries=1\n---\n csu/libc-start.c                        |   2 +-\n elf/Makefile                            |   4 +\n elf/cache.c                             |   3 +-\n elf/dl-tunables.c                       |  80 ++++++++++++++-\n elf/dl-tunables.h                       |   2 +-\n elf/ldconfig-parse.c                    |   6 +-\n elf/ldconfig.c                          |   3 +\n elf/tst-tunconf1.c                      |  36 +++++++\n elf/tst-tunconf1.root/etc/tunables.conf |  15 +++\n elf/tst-tunconf1.root/ldconfig.run      |   0\n elf/tst-tunconf1.root/postclean.req     |   0\n elf/tunconf.c                           | 130 +++++++++++++++++++++++-\n elf/tunconf.h                           |   3 +\n sysdeps/mach/hurd/dl-sysdep.c           |   2 +-\n sysdeps/unix/sysv/linux/dl-sysdep.c     |   2 +-\n 15 files changed, 273 insertions(+), 15 deletions(-)\n create mode 100644 elf/tst-tunconf1.c\n create mode 100644 elf/tst-tunconf1.root/etc/tunables.conf\n create mode 100644 elf/tst-tunconf1.root/ldconfig.run\n create mode 100644 elf/tst-tunconf1.root/postclean.req",
    "diff": "diff --git a/csu/libc-start.c b/csu/libc-start.c\nindex 1c58561bce..ae36170045 100644\n--- a/csu/libc-start.c\n+++ b/csu/libc-start.c\n@@ -264,7 +264,7 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),\n   _dl_aux_init (auxvec);\n # endif\n \n-  __tunables_init (__environ);\n+  __tunables_init (__environ, argv);\n \n   ARCH_INIT_CPU_FEATURES ();\n \ndiff --git a/elf/Makefile b/elf/Makefile\nindex 5398fe0d2c..4fbd03cefc 100644\n--- a/elf/Makefile\n+++ b/elf/Makefile\n@@ -323,6 +323,7 @@ tests-internal := \\\n   $(tests-static-internal) \\\n   tst-tls1 \\\n   tst-tls_tp_offset \\\n+  tst-tunconf1 \\\n   # tests-internal\n \n tests-static := $(tests-static-normal) $(tests-static-internal)\n@@ -333,6 +334,8 @@ tests-static += \\\n   tst-tls9-static \\\n   # tests-static\n \n+tst-tunconf1-ENV = GLIBC_TUNABLES=glibc.malloc.tcache_count=5\n+\n static-dlopen-environment = \\\n   LD_LIBRARY_PATH=$(ld-library-path):$(common-objpfx)dlfcn\n tst-tls9-static-ENV = $(static-dlopen-environment)\n@@ -563,6 +566,7 @@ tests-container += \\\n   tst-pldd \\\n   tst-preload-pthread-libc \\\n   tst-rootdir \\\n+  tst-tunconf1 \\\n   # tests-container\n \n test-srcs = \\\ndiff --git a/elf/cache.c b/elf/cache.c\nindex fe8f66366f..4655cf961f 100644\n--- a/elf/cache.c\n+++ b/elf/cache.c\n@@ -304,9 +304,10 @@ print_extensions (struct cache_extension_all_loaded *ext,\n \t      >= (void *) & tec[count]);\n       for (i = 0; i < count; ++ i)\n \t{\n-\t  printf(\"  [%d] %s : %s [flags 0x%08x\",\n+\t  printf(\"  [%d] %s (%d) : %s [flags 0x%08x\",\n \t\t i,\n \t\t cache_data + tec[i].name_offset,\n+\t\t tec[i].tunable_id,\n \t\t cache_data + tec[i].value_offset,\n \t\t tec[i].flags);\n \t  if (tec[i].flag_offset != 0)\ndiff --git a/elf/dl-tunables.c b/elf/dl-tunables.c\nindex 20e4056d74..c9dc6b8b62 100644\n--- a/elf/dl-tunables.c\n+++ b/elf/dl-tunables.c\n@@ -292,7 +292,7 @@ parse_tunables (const char *valstring)\n    ENV_ALIAS to find values.  Later we will also use the tunable names to find\n    values.  */\n void\n-__tunables_init (char **envp)\n+__tunables_init (char **envp, char **argv)\n {\n   char *envname = NULL;\n   char *envval = NULL;\n@@ -304,6 +304,15 @@ __tunables_init (char **envp)\n     TUNABLE_SET (glibc, malloc, hugetlb, 1);\n \n #if defined(SHARED) && defined (USE_LDCONFIG)\n+  const char *prog_name = (argv && argv[0]) ? argv[0] : \"\";\n+  int prog_name_len = -1;\n+  const char *base_name = NULL;\n+  int base_name_len = -1;\n+#ifdef PATH_MAX\n+  char exebuf[PATH_MAX];\n+#else\n+  char exebuf[256];\n+#endif\n   const struct tunable_header_cached *thc;\n   const char *td;\n \n@@ -336,9 +345,70 @@ __tunables_init (char **envp)\n \t      if (tid == -1)\n \t\tcontinue;\n \t    }\n-\t  /* At this point, TID is valid for the tunable we want.  See\n-\t     if the parsed type matches the desired type.  */\n-\n+\t  /* At this point, TID is valid for the tunable we want.  */\n+\n+\t  if (tec->flags & TUNCONF_EXCLUDE_SECURE && __libc_enable_secure)\n+\t    goto skip_due_to_filter;\n+\t  if (tec->flags & TUNCONF_EXCLUDE_UNSECURE && !__libc_enable_secure)\n+\t    goto skip_due_to_filter;\n+\n+\t  /* Apply selected filter, if any.  */\n+\t  switch (tec->flags & TUNCONF_FLAG_FILTER) {\n+\t  case TUNCONF_FILTER_PERPROC:\n+\t    /* Perform one-time calculations that aren't needed if we\n+\t       don't use this filter.  */\n+\t    if (prog_name_len == -1)\n+\t      {\n+\t\tssize_t n = readlink (\"/proc/self/exe\",\n+\t\t\t\t      exebuf, sizeof (exebuf) - 1);\n+\t\tif (n > 0 && n < sizeof(exebuf)-1)\n+\t\t  {\n+\t\t    /* If /proc/self/exe exists and we can read it,\n+\t\t       it's more reliable than argv[] so use it.  */\n+\t\t    exebuf[n] = '\\0';\n+\t\t    prog_name = exebuf;\n+\t\t  }\n+\t\telse if (__libc_enable_secure)\n+\t\t  prog_name = NULL;\n+\t\tif (prog_name != NULL)\n+\t\t  {\n+\t\t    const char *slash = NULL, *cp;\n+\t\t    for (cp = prog_name; *cp; ++ cp)\n+\t\t      if (*cp == '/')\n+\t\t\tslash = cp;\n+\t\t    if (slash)\n+\t\t      base_name = slash + 1;\n+\t\t    else\n+\t\t      base_name = prog_name;\n+\t\t    prog_name_len = strlen (prog_name);\n+\t\t    base_name_len = strlen (base_name);\n+\t\t  }\n+\t      }\n+\t    /* prog_name and the cached string are both NUL terminated.  */\n+\t    if (prog_name)\n+\t      {\n+\t\tif (((const char *)(td + tec->flag_offset))[0] == '/')\n+\t\t  {\n+\t\t    if (memcmp (prog_name, td + tec->flag_offset, prog_name_len) != 0)\n+\t\t      goto skip_due_to_filter;\n+\t\t  }\n+\t\telse\n+\t\t  {\n+\t\t    if (memcmp (base_name, td + tec->flag_offset, base_name_len) != 0)\n+\t\t      goto skip_due_to_filter;\n+\t\t  }\n+\t      }\n+\t    else\n+\t      /* Program is AT_SECURE but the only source of program\n+\t\t name is argv[0], which is not secure, so we do not\n+\t\t match any name-based filter.  */\n+\t      goto skip_due_to_filter;\n+\t    break;\n+\t  default:\n+\t    break;\n+\t  }\n+\n+\t  /* See if the parsed type matches the desired type.  */\n \t  if (tunable_list[tid].type.type_code == TUNABLE_TYPE_STRING)\n \t    {\n \t      /* This is a memory leak but there's no easy way around\n@@ -361,6 +431,8 @@ __tunables_init (char **envp)\n \t\t\t\t      value, strlen (value));\n \t\t}\n \t    }\n+\n+\tskip_due_to_filter:;\n \t}\n     }\n #endif /* defined(SHARED) && defined (USE_LDCONFIG) */\ndiff --git a/elf/dl-tunables.h b/elf/dl-tunables.h\nindex 45aeed47bc..3f34329614 100644\n--- a/elf/dl-tunables.h\n+++ b/elf/dl-tunables.h\n@@ -47,7 +47,7 @@ typedef void (*tunable_callback_t) (tunable_val_t *);\n \n #include \"dl-tunable-list.h\"\n \n-extern void __tunables_init (char **);\n+extern void __tunables_init (char **, char **);\n extern void __tunables_print (void);\n extern bool __tunable_is_initialized (tunable_id_t);\n extern void __tunable_get_val (tunable_id_t, void *, tunable_callback_t);\ndiff --git a/elf/ldconfig-parse.c b/elf/ldconfig-parse.c\nindex b7bb664eb5..baddfdbac0 100644\n--- a/elf/ldconfig-parse.c\n+++ b/elf/ldconfig-parse.c\n@@ -47,8 +47,10 @@ ldconfig_parse_config_1 (const char *filename, bool do_chroot,\n \n      opt_chroot - If non-NULL, all paths are relative to this.\n \n-     callback - for each non-blank line in the file, this function is called\n-\twith the line and it's location.\n+     callback - for each non-blank line in the file, this function is\n+\tcalled with the line and it's location.  Will also be called\n+\twith a NULL line at the start and end of each file, for\n+\tfile-scoped config items.\n  */\n \n void\ndiff --git a/elf/ldconfig.c b/elf/ldconfig.c\nindex 11b063eb5c..1ea55400f3 100644\n--- a/elf/ldconfig.c\n+++ b/elf/ldconfig.c\n@@ -435,6 +435,9 @@ add_dir_1 (const char *line, const char *from_file, int from_line)\n static void\n add_dir_callback (char *line, const char *from_file, int from_line)\n {\n+  /* Denotes file boundaries.  Not needed here.  */\n+  if (line == NULL)\n+    return;\n   if (!strncasecmp (line, \"hwcap\", 5) && isblank (line[5]))\n     error (0, 0, _(\"%s:%u: hwcap directive ignored\"), from_file, from_line);\n   else\ndiff --git a/elf/tst-tunconf1.c b/elf/tst-tunconf1.c\nnew file mode 100644\nindex 0000000000..c95a7cb8ba\n--- /dev/null\n+++ b/elf/tst-tunconf1.c\n@@ -0,0 +1,36 @@\n+/* Test that the tunables cache can override env vars.\n+   Copyright (C) 2026 Free Software Foundation, Inc.\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 <stdio.h>\n+#include <support/check.h>\n+\n+#include \"dl-tunables.h\"\n+\n+static int\n+do_test (void)\n+{\n+  size_t tcache_count = TUNABLE_GET_FULL (glibc, malloc, tcache_count, size_t, NULL);\n+  size_t tcache_max = TUNABLE_GET_FULL (glibc, malloc, tcache_max, size_t, NULL);\n+  printf(\"tcache count is %ld (should be 5, from env)\\n\", (long)tcache_count);\n+  TEST_COMPARE ((long)tcache_count, 5);\n+  printf(\"tcache max is %ld (should be 4, from /etc)\\n\", (long)tcache_max);\n+  TEST_COMPARE ((long)tcache_max, 4);\n+  return 0;\n+}\n+\n+#include <support/test-driver.c>\ndiff --git a/elf/tst-tunconf1.root/etc/tunables.conf b/elf/tst-tunconf1.root/etc/tunables.conf\nnew file mode 100644\nindex 0000000000..6cd6c8a949\n--- /dev/null\n+++ b/elf/tst-tunconf1.root/etc/tunables.conf\n@@ -0,0 +1,15 @@\n+# These test the parser for both the overridability characters as well as\n+# tunables that either never exist, or only exist on some platforms.\n+!glibc.foo=19\n+-glibc.cpu.cached_memopt=1\n++glibc.cpu.hwcaps=some,random,string\n+@glibc.test_secure=1\n+$glibc.test_unsecure=1\n+\n+# These are checked inside the test case\n+glibc.malloc.tcache_max=6\n+$glibc.malloc.tcache_count=3\n+[proc:/bin/ls]\n+glibc.malloc.tcache_max=7\n+[proc:tst-tunconf1]\n+glibc.malloc.tcache_max=4\ndiff --git a/elf/tst-tunconf1.root/ldconfig.run b/elf/tst-tunconf1.root/ldconfig.run\nnew file mode 100644\nindex 0000000000..e69de29bb2\ndiff --git a/elf/tst-tunconf1.root/postclean.req b/elf/tst-tunconf1.root/postclean.req\nnew file mode 100644\nindex 0000000000..e69de29bb2\ndiff --git a/elf/tunconf.c b/elf/tunconf.c\nindex 1b7bf0ac2b..8fae4bb652 100644\n--- a/elf/tunconf.c\n+++ b/elf/tunconf.c\n@@ -66,12 +66,16 @@ typedef enum {\n struct tunable_entry_int {\n   struct stringtable_entry *name;\n   struct stringtable_entry *value;\n+  struct stringtable_entry *filter;\n   TOP top;\n+  bool exclude_secure:1;\n+  bool exclude_unsecure:1;\n   int tunable_id;\n   int value_is_negative:1;\n   int value_was_parsed:1;\n   unsigned long long value_ull;\n   signed long long value_sll;\n+  long filter_flags;\n \n   struct tunable_entry_int *next;\n };\n@@ -79,8 +83,84 @@ struct tunable_entry_int {\n struct tunable_entry_int *entry_list;\n struct tunable_entry_int **entry_list_next = &entry_list;\n \n+static int filter_flags = 0;\n+static char *filter_string = NULL;\n+\n /*----------------------------------------------------------------------*/\n \n+static void\n+clear_filter (void)\n+{\n+  free (filter_string);\n+  filter_string = NULL;\n+  filter_flags = 0;\n+}\n+\n+/* Filters are lines the are bracketed, like\n+   [prog:foo]\n+*/\n+static void\n+parse_filter (char *line, const char *filename, int lineno)\n+{\n+  const char *colon = NULL;\n+  const char *right_bracket = NULL;\n+  const char *cp;\n+\n+  for (cp = line; *cp != 0; ++cp)\n+    {\n+      if (*cp == ':')\n+\tcolon = cp;\n+      if (*cp == ']')\n+\t{\n+\t  right_bracket = cp;\n+\t  break;\n+\t}\n+    }\n+  /* Special case: [] means \"no filter\" */\n+  if (right_bracket != NULL && right_bracket == line + 1)\n+    {\n+      clear_filter ();\n+      return;\n+    }\n+  if (colon == NULL)\n+    {\n+      error_at_line (0, 0, filename, lineno,\n+\t\t     \"syntax error, filter line ignored: `%s' (missing ':')\\n\",\n+\t\t     line);\n+      return;\n+    }\n+  if (right_bracket == NULL)\n+    {\n+      error_at_line (0, 0, filename, lineno,\n+\t\t     \"syntax error, filter line ignored: `%s' (missing ']')\\n\",\n+\t\t     line);\n+      return;\n+    }\n+\n+  if (filter_string != NULL)\n+    {\n+      clear_filter ();\n+    }\n+\n+  if (memcmp (\"proc\", line + 1, colon - line - 1) == 0)\n+    {\n+      /* Consider this example: [proc:foo] ...\"  */\n+      /* We allocate 4 bytes, [0] through [3].  */\n+      filter_string = (char *) malloc (right_bracket - colon);\n+      /* We copy \"foo\" for 3 bytes, [0] through [2].  */\n+      memcpy (filter_string, colon + 1, right_bracket - colon - 1);\n+      /*  [3] = 0 so now \"foo\\0\".  */\n+      filter_string [right_bracket - colon - 1] = 0;\n+      filter_flags = TUNCONF_FILTER_PERPROC;\n+    }\n+\n+  else\n+    error_at_line (0, 0, filename, lineno,\n+\t\t   \"unrecognized filter `%.*s', ignored\\n\",\n+\t\t   (int)(colon - line - 1), line + 1);\n+}\n+\n+\n static void\n add_tunable (char *line, const char *filename, int lineno)\n {\n@@ -91,12 +171,20 @@ add_tunable (char *line, const char *filename, int lineno)\n   char *orig_line;\n   struct tunable_entry_int *entry;\n   int i, id;\n+  bool exclude_secure = 0, exclude_unsecure = 0;\n+\n+  /* Denotes file boundaries.  */\n+  if (line == NULL)\n+    {\n+      clear_filter();\n+      return;\n+    }\n \n   orig_line = line;\n \n   /* Leading whitespace has already been stripped.  */\n \n-  if (*line == '!' || *line == '+' || *line == '-')\n+  while (*line)\n     {\n       switch (*line)\n \t{\n@@ -109,11 +197,25 @@ add_tunable (char *line, const char *filename, int lineno)\n \tcase '-':\n \t  top = TOP_DENY;\n \t  break;\n+\tcase '@':\n+\t  exclude_unsecure = 1;\n+\t  break;\n+\tcase '$':\n+\t  exclude_secure = 1;\n+\t  break;\n+\tcase '[':\n+\t  parse_filter (line, filename, lineno);\n+\t  return;\n+\tcase ' ':\n+\tcase '\\t':\n+\t  break;\n+\n+\tdefault:\n+\t  goto done;\n \t}\n       line ++;\n-      while (*line && isspace(*line))\n-\tline ++;\n     }\n+ done:\n \n   /* NAME now points to the start of the tunable name.  */\n   name = line;\n@@ -174,6 +276,14 @@ add_tunable (char *line, const char *filename, int lineno)\n   entry->value = cache_store_string (value);\n   entry->tunable_id = id;\n   entry->top = top;\n+  entry->exclude_secure = exclude_secure;\n+  entry->exclude_unsecure = exclude_unsecure;\n+\n+  if (filter_flags)\n+    {\n+      entry->filter_flags = filter_flags;\n+      entry->filter = cache_store_string (filter_string);\n+    }\n \n   *entry_list_next = entry;\n   entry_list_next = & (entry->next);\n@@ -248,11 +358,23 @@ get_tunconf_ext (uint32_t string_table_offset)\n \t  tec->flags |= TUNCONF_OVERRIDE_DENY;\n \t  break;\n \t}\n+      if (tei->exclude_secure)\n+\ttec->flags |= TUNCONF_EXCLUDE_SECURE;\n+      if (tei->exclude_unsecure)\n+\ttec->flags |= TUNCONF_EXCLUDE_UNSECURE;\n \n       tec->tunable_id = tei->tunable_id;\n       tec->name_offset = tei->name->offset + string_table_offset;\n       tec->value_offset = tei->value->offset + string_table_offset;\n-      tec->flag_offset = 0;\n+\n+      if (tei->filter_flags != 0)\n+\t{\n+\t  tec->flag_offset = tei->filter->offset + string_table_offset;\n+\t  tec->flags |= tei->filter_flags;\n+\t}\n+      else\n+\ttec->flag_offset = 0;\n+\n       tec->unused_1 = 0;\n       if (tei->value_is_negative)\n \ttec->parsed_value = (uint64_t) tei->value_sll;\ndiff --git a/elf/tunconf.h b/elf/tunconf.h\nindex 9551119167..e880aa574a 100644\n--- a/elf/tunconf.h\n+++ b/elf/tunconf.h\n@@ -10,6 +10,9 @@\n #define TUNCONF_OVERRIDE_STRICTER\t0x00000008\n #define TUNCONF_OVERRIDE_DENY\t\t0x0000000C\n \n+#define TUNCONF_EXCLUDE_SECURE\t\t0x00000010\n+#define TUNCONF_EXCLUDE_UNSECURE\t0x00000020\n+\n #define TUNCONF_FLAG_FILTER\t\t0x0000ff00\n #define TUNCONF_FILTER_PERPROC\t\t0x00000100\n \ndiff --git a/sysdeps/mach/hurd/dl-sysdep.c b/sysdeps/mach/hurd/dl-sysdep.c\nindex 0e348d6440..fe6d453756 100644\n--- a/sysdeps/mach/hurd/dl-sysdep.c\n+++ b/sysdeps/mach/hurd/dl-sysdep.c\n@@ -98,7 +98,7 @@ _dl_sysdep_start (void **start_argptr,\n \n       __libc_enable_secure = _dl_hurd_data->flags & EXEC_SECURE;\n \n-      __tunables_init (_environ);\n+      __tunables_init (_environ, _dl_argv);\n \n       /* Initialize DSO sorting algorithm after tunables.  */\n       _dl_sort_maps_init ();\ndiff --git a/sysdeps/unix/sysv/linux/dl-sysdep.c b/sysdeps/unix/sysv/linux/dl-sysdep.c\nindex cb1f94ee23..c2701f274c 100644\n--- a/sysdeps/unix/sysv/linux/dl-sysdep.c\n+++ b/sysdeps/unix/sysv/linux/dl-sysdep.c\n@@ -107,7 +107,7 @@ _dl_sysdep_start (void **start_argptr,\n \n   dl_hwcap_check ();\n \n-  __tunables_init (_environ);\n+  __tunables_init (_environ, (char **) (start_argptr + 1));\n \n   /* Initialize DSO sorting algorithm after tunables.  */\n   _dl_sort_maps_init ();\n",
    "prefixes": [
        "v7",
        "4/4"
    ]
}