From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-oi1-x231.google.com (mail-oi1-x231.google.com [IPv6:2607:f8b0:4864:20::231]) by sourceware.org (Postfix) with ESMTPS id 7168E385783A for ; Tue, 18 Jan 2022 19:42:25 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 7168E385783A Received: by mail-oi1-x231.google.com with SMTP id e81so517850oia.6 for ; Tue, 18 Jan 2022 11:42:25 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:date:mime-version:user-agent:subject :content-language:to:cc:references:from:in-reply-to :content-transfer-encoding; bh=qCokToZAF1e6vW8MF0jzDYKk3l8ub03gpOpjGWSpsm8=; b=rCyywTkMaekla9MCaZQCJm4whWPoWeOZBhgNc8cgXG0YSO9cdfjbgsbGO5u1Au22b3 DFd8oZsAKw+oH/DYpAQFKmA1yVufO6UOkpnR+bYCeTJFILTJmmtg0XBWZj2dmwiETqDw RUxHDPmL/0aP64BlGmLd2t0OZbNgwN1KFxNTg1JyE2qApTk0U7M5HY3w1em4UjeXUNxv v4mELrJKJIOVNQCYSxd5GMnz0uUWYpfkudsYFVA+cpZAWMx791kuYFzvrr1etDMaKMQK U+8VTLNBbyfAYBFBkcicDYhqEQBWGqnteIARBGVcpOF+WZK7b4cwO24TxY1IybjyUZt6 ncWQ== X-Gm-Message-State: AOAM532m8k05rt0v70MtE54n+lurZtmrGuJa440pcfwicrDscs+jQ2Fg TEorz9ayip8Exek8pZT2bxzzTg== X-Google-Smtp-Source: ABdhPJzxJG4HFjJufRL4zn3xsqC8xCp6U/K4g3vhlPohBf/V0axSyZnBIA4YthPdpuWaBT7JDJb0hg== X-Received: by 2002:a05:6808:607:: with SMTP id y7mr61182oih.131.1642534944696; Tue, 18 Jan 2022 11:42:24 -0800 (PST) Received: from ?IPV6:2804:431:c7cb:989a:419b:3fe6:8885:ab23? ([2804:431:c7cb:989a:419b:3fe6:8885:ab23]) by smtp.gmail.com with ESMTPSA id g17sm908657oiy.32.2022.01.18.11.42.23 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 18 Jan 2022 11:42:24 -0800 (PST) Message-ID: <3857166b-e5ef-b988-bd2a-57d5900ab170@linaro.org> Date: Tue, 18 Jan 2022 16:42:22 -0300 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.5.0 Subject: Re: [PATCH 1/3] support: Add helpers to create paths longer than PATH_MAX Content-Language: en-US To: Siddhesh Poyarekar , libc-alpha@sourceware.org Cc: fweimer@redhat.com References: <20220118090728.1825487-1-siddhesh@sourceware.org> <20220118090728.1825487-2-siddhesh@sourceware.org> From: Adhemerval Zanella In-Reply-To: <20220118090728.1825487-2-siddhesh@sourceware.org> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-13.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, NICE_REPLY_A, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 18 Jan 2022 19:42:27 -0000 On 18/01/2022 06:07, Siddhesh Poyarekar wrote: > Add new helpers support_create_and_chdir_toolong_temp_directory and > support_chdir_toolong_temp_directory to create and descend into > directory trees longer than PATH_MAX. > > Signed-off-by: Siddhesh Poyarekar > --- > support/temp_file.c | 157 +++++++++++++++++++++++++++++++++++++++++--- > support/temp_file.h | 11 ++++ > 2 files changed, 160 insertions(+), 8 deletions(-) > > diff --git a/support/temp_file.c b/support/temp_file.c > index e7bb8aadb9..c3e83912ac 100644 > --- a/support/temp_file.c > +++ b/support/temp_file.c > @@ -36,14 +36,31 @@ static struct temp_name_list > struct temp_name_list *next; > char *name; > pid_t owner; > + bool toolong; > } *temp_name_list; > > /* Location of the temporary files. Set by the test skeleton via > support_set_test_dir. The string is not be freed. */ > static const char *test_dir = _PATH_TMP; > > -void > -add_temp_file (const char *name) > +/* Name of subdirectories in a too long temporary directory tree. */ > +static char toolong_subdir[NAME_MAX + 1]; > + > +/* Return the maximum size of path on the target. */ > +static inline size_t > +get_path_max (void) > +{ > +#ifdef PATH_MAX > + return PATH_MAX; > +#else > + size_t path_max = pathconf ("/", _PC_PATH_MAX); > + return (path_max < 0 ? 1024 > + : path_max <= PTRDIFF_MAX ? path_max : PTRDIFF_MAX); > +#endif > +} > + > +static void > +add_temp_file_internal (const char *name, bool toolong) > { > struct temp_name_list *newp > = (struct temp_name_list *) xcalloc (sizeof (*newp), 1); > @@ -53,12 +70,19 @@ add_temp_file (const char *name) > newp->name = newname; > newp->next = temp_name_list; > newp->owner = getpid (); > + newp->toolong = toolong; > temp_name_list = newp; > } > else > free (newp); > } > > +void > +add_temp_file (const char *name) > +{ > + add_temp_file_internal (name, false); > +} > + > int > create_temp_file_in_dir (const char *base, const char *dir, char **filename) > { > @@ -90,8 +114,8 @@ create_temp_file (const char *base, char **filename) > return create_temp_file_in_dir (base, test_dir, filename); > } > > -char * > -support_create_temp_directory (const char *base) > +static char * > +create_temp_directory_internal (const char *base, bool toolong) > { > char *path = xasprintf ("%s/%sXXXXXX", test_dir, base); > if (mkdtemp (path) == NULL) > @@ -99,16 +123,124 @@ support_create_temp_directory (const char *base) > printf ("error: mkdtemp (\"%s\"): %m", path); > exit (1); > } > - add_temp_file (path); > + add_temp_file_internal (path, toolong); > return path; > } > > -/* Helper functions called by the test skeleton follow. */ > +char * > +support_create_temp_directory (const char *base) > +{ > + return create_temp_directory_internal (base, false); > +} > + > +static void > +ensure_toolong_subdir_initialized (void) > +{ > + for (size_t i = 0; i < NAME_MAX; i++) > + if (toolong_subdir[i] != 'X') > + { > + printf ("uninitialized toolong directory tree\n"); > + exit (1); > + } > +} Maybe use FAIL_EXIT1 here? > + > +char * > +support_create_and_chdir_toolong_temp_directory (const char *basename) > +{ > + size_t path_max = get_path_max (); > + > + char *base = create_temp_directory_internal (basename, true); > + > + if (chdir (base) != 0) > + { > + printf ("error creating toolong base: chdir (\"%s\"): %m", base); > + exit (1); > + } > + Use xchdir. > + memset (toolong_subdir, 'X', sizeof (toolong_subdir) - 1); > + toolong_subdir[NAME_MAX] = '\0'; > + > + /* Create directories and descend into them so that the final path is larger > + than PATH_MAX. */ > + for (size_t i = 0; i <= path_max / sizeof (toolong_subdir); i++) > + { > + if (mkdir (toolong_subdir, S_IRWXU) != 0) > + { > + printf ("error creating toolong subdir: mkdir (\"%s\"): %m", > + toolong_subdir); > + exit (1); > + } Use xmkdir. > + if (chdir (toolong_subdir) != 0) Use xchdir. > + { > + printf ("error creating toolong subdir: chdir (\"%s\"): %m", > + toolong_subdir); > + exit (1); > + } > + } > + return base; > +} > > void > -support_set_test_dir (const char *path) > +support_chdir_toolong_temp_directory (const char *base) > { > - test_dir = path; > + size_t path_max = get_path_max (); > + ensure_toolong_subdir_initialized (); > + > + if (chdir (base) != 0) > + { > + printf ("error: chdir (\"%s\"): %m", base); > + exit (1); > + } > + > + for (size_t i = 0; i <= path_max / sizeof (toolong_subdir); i++) > + if (chdir (toolong_subdir) != 0) Use xchdir. > + { > + printf ("error subdir: chdir (\"%s\"): %m", toolong_subdir); > + exit (1); > + } > +} > + > +/* Helper functions called by the test skeleton follow. */ > + > +static void > +remove_toolong_subdirs (const char *base) > +{ > + size_t path_max = get_path_max (); > + > + ensure_toolong_subdir_initialized (); > + > + if (chdir (base) != 0) > + { > + printf ("warning: toolong cleanup base failed: chdir (\"%s\"): %m\n", > + base); > + return; > + } > + > + /* Descend. */ > + int levels = 0; > + for (levels = 0; levels <= path_max / sizeof (toolong_subdir); levels++) > + if (chdir (toolong_subdir) != 0) > + { > + printf ("warning: toolong cleanup failed: chdir (\"%s\"): %m\n", > + toolong_subdir); > + return; > + } > + > + /* Ascend and remove. */ > + while (--levels >= 0) > + { > + if (chdir ("..") != 0) > + { > + printf ("warning: toolong cleanup failed: chdir (\"..\"): %m\n"); > + return; > + } > + if (remove (toolong_subdir) != 0) > + { > + printf ("warning: could not remove subdirectory: %s: %m\n", > + toolong_subdir); > + return; > + } > + } > } Throwing an warning should be fine in such cases. > > void > @@ -123,6 +255,9 @@ support_delete_temp_files (void) > around, to prevent PID reuse.) */ > if (temp_name_list->owner == pid) > { > + if (temp_name_list->toolong) > + remove_toolong_subdirs (temp_name_list->name); > + > if (remove (temp_name_list->name) != 0) > printf ("warning: could not remove temporary file: %s: %m\n", > temp_name_list->name); > @@ -147,3 +282,9 @@ support_print_temp_files (FILE *f) > fprintf (f, ")\n"); > } > } > + > +void > +support_set_test_dir (const char *path) > +{ > + test_dir = path; > +} > diff --git a/support/temp_file.h b/support/temp_file.h > index 50a443abe4..de01fbbceb 100644 > --- a/support/temp_file.h > +++ b/support/temp_file.h > @@ -19,6 +19,8 @@ > #ifndef SUPPORT_TEMP_FILE_H > #define SUPPORT_TEMP_FILE_H > > +#include > +#include > #include > > __BEGIN_DECLS > @@ -44,6 +46,15 @@ int create_temp_file_in_dir (const char *base, const char *dir, > returns. The caller should free this string. */ > char *support_create_temp_directory (const char *base); > > +/* Create a temporary directory tree that is longer than PATH_MAX and schedule > + it for deletion. BASENAME is used as a prefix for the unique directory > + name, which the function returns. The caller should free this string. */ > +char *support_create_and_chdir_toolong_temp_directory (const char *basename); > + > +/* Change into the innermost directory of the directory tree BASE, which was > + created using support_create_and_chdir_toolong_temp_directory. */ > +void support_chdir_toolong_temp_directory (const char *base); > + > __END_DECLS > > #endif /* SUPPORT_TEMP_FILE_H */