From patchwork Mon May 22 13:25:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Costas Argyris X-Patchwork-Id: 97433 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp1447890vqo; Mon, 22 May 2023 06:26:22 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ4VexbxjZ1b3FHKEedztoEC0zDbHlWdsrVYkalPgEVNtEAwFK2d9PXzcT+5sMga2G8D5ANI X-Received: by 2002:aa7:ce04:0:b0:506:9805:7b56 with SMTP id d4-20020aa7ce04000000b0050698057b56mr9680880edv.32.1684761981876; Mon, 22 May 2023 06:26:21 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1684761981; cv=none; d=google.com; s=arc-20160816; b=U5MNNr3r1lF7z9HxLeOJm6BLAgX5qdDCwx8tzRxcNNQqLQf0EEFuE05m9bKenGZD4t kFEwbxmkL5fgE79Rn93K0C4/fErzFdBW8SQTZpg7OHACvPadzhVbgc2vSqF6/jCHq4Ld 5xd+2xcs2HOMJ1+nYMR1zj5lrrouZsajl3VN4cLZ76kioALozQB0mk5RVK7zATxuEnTc 8nGHbhBKyXXMNKz17vpbbtbDMyzqseuJrkCrcrdfufMKSn7oeFIQZDJfQ4ttdzT303kR dJTfLjXsk4SnAbTbuKcSPaPX2fVAR2J3t6oAiWTL83I98ztLfANdJLvs+8p2AaYuzI0F LeHg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:from:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence:cc:to:subject :message-id:date:mime-version:dmarc-filter:delivered-to :dkim-signature:dkim-filter; bh=psU1fB2NQtEddP4eXdPHCiPjpcuz9ByolYjELscW+c0=; b=K/8DSBAUvoCehmhjhzXdZLd+Ii8wuY5ViuF249UM+Dp9Kg6a1TMhaHBlKprx9Dc3lm ADixlLRBQxPlc0Cc32MaKs49Mm1no2aLQCgZg0m1KX5meKB9R4DxNXE+2jBT9hLG32Hl hEcuMeT4IL2C/ZKOX39DDda/QbvVrFKvoE+B922Ru9tJvKNXkdKufXymMd/wMhCz3iuL g86s8r9wYNc95QrzFFy6CSfZkz9gC8RzGjWXMO0Lqrkjl2fo5p8J8E5Ks3hVwzGD8Gkg E7wD82vZKeKtLhnIMIt5nxmuyp3r6yFL1IC/tFJwXFRSGE97qsR7WwODj43G185gbyRa k+1g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b="s/AMXDiU"; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from sourceware.org (server2.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id l11-20020a056402028b00b0050d9b5885fesi2983843edv.217.2023.05.22.06.26.21 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 22 May 2023 06:26:21 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b="s/AMXDiU"; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id C4AC83858D38 for ; Mon, 22 May 2023 13:26:20 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C4AC83858D38 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1684761980; bh=psU1fB2NQtEddP4eXdPHCiPjpcuz9ByolYjELscW+c0=; h=Date:Subject:To:Cc:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From:Reply-To:From; b=s/AMXDiUOw34p7GnVxfcx/By4Ydwnw0u8vpiIRefFs07TuhnP+KoKi+p8R/I2F+3r Zh0PfjqvuaTo0yLa2Omp6bfvowc7endsN6P2ZAH9n3zB0vMFlS0+BmFxPrsMoIe77s mpurn/J+og82LP6u9E/fMJvFrn/QV5OYIWpP/eXg= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-ed1-x534.google.com (mail-ed1-x534.google.com [IPv6:2a00:1450:4864:20::534]) by sourceware.org (Postfix) with ESMTPS id 0F7BC3858D35 for ; Mon, 22 May 2023 13:25:35 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 0F7BC3858D35 Received: by mail-ed1-x534.google.com with SMTP id 4fb4d7f45d1cf-510e419d701so9417306a12.1 for ; Mon, 22 May 2023 06:25:35 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1684761933; x=1687353933; h=cc:to:subject:message-id:date:from:mime-version:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=uPGG+Wkixl19HkmBNSrSAJQs3aiOCgI2aJUzqvkFv9M=; b=lH1+/wyTrE3lLnuAj3SU0pHtlNvrnSnRACMYzAds8du64KPPLEYdM/NG9BAi2k0LzE j7uTBMOKyf5eVgeQyML8QMBDVDts+B/2j1/s0fWW+LGLGGSn4iGOe2m1X3NlMqEllnbt tM3pZi+XDmukqs4Py29wXHuuxZZGtiZbrlfnrWua3aq/sv7BeFSdKys8N9WcFxOtI1MK g98HhRH7Jg/QjGXV9RbYJzRaCbJIesFO9r0d5AnoY1OxpVJt2/ZleFaTp8aqpR/c+H7J g7a4gAh8WDKBXrXoVZ6djNm3LW1APjeNg6sjKL4l6gXImJWQFD//msJrcGvXSE+Nyrzg +CGQ== X-Gm-Message-State: AC+VfDzfBWjIOGh7SKvvj7Dys5x0PxCGGJFGDtSkCpwA1Rdsml2TjnaN ixBr3Fboyo6BOGPIj0+H9pwWmLTBHeg01y94YQZzUXUVQeJd2g== X-Received: by 2002:aa7:c6c8:0:b0:510:6217:9994 with SMTP id b8-20020aa7c6c8000000b0051062179994mr7712689eds.39.1684761932501; Mon, 22 May 2023 06:25:32 -0700 (PDT) MIME-Version: 1.0 Date: Mon, 22 May 2023 14:25:21 +0100 Message-ID: Subject: [PATCH] libiberty: On Windows pass a >32k cmdline through a response file. To: gcc-patches@gcc.gnu.org Cc: Jonathan Yong <10walls@gmail.com> X-Spam-Status: No, score=-7.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, HTML_MESSAGE, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-Content-Filtered-By: Mailman/MimeDel 2.1.29 X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Costas Argyris via Gcc-patches From: Costas Argyris Reply-To: Costas Argyris Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1766600979882967408?= X-GMAIL-MSGID: =?utf-8?q?1766600979882967408?= Currently on Windows, when CreateProcess is called with a command-line that exceeds the 32k Windows limit, we get a very bad error: "CreateProcess: No such file or directory" This patch detects the case where this would happen and writes the long command-line to a temporary response file and calls CreateProcess with @file instead. From 5c7237c102cdaca34e5907cd25c31610bda51919 Mon Sep 17 00:00:00 2001 From: Costas Argyris Date: Mon, 22 May 2023 13:55:56 +0100 Subject: [PATCH] libiberty: On Windows, pass a >32k cmdline through a response file. pex-win32.c (win32_spawn): If the command line for CreateProcess exceeds the 32k Windows limit, try to store it in a temporary response file and call CreateProcess with @file instead (PR71850). Signed-off-by: Costas Argyris --- libiberty/pex-win32.c | 57 +++++++++++++++++++++++++++++++++---------- 1 file changed, 44 insertions(+), 13 deletions(-) diff --git a/libiberty/pex-win32.c b/libiberty/pex-win32.c index 23c6c190a2c..0fd8b38734c 100644 --- a/libiberty/pex-win32.c +++ b/libiberty/pex-win32.c @@ -569,7 +569,8 @@ env_compare (const void *a_ptr, const void *b_ptr) * target is not actually an executable, such as if it is a shell script. */ static pid_t -win32_spawn (const char *executable, +win32_spawn (struct pex_obj *obj, + const char *executable, BOOL search, char *const *argv, char *const *env, /* array of strings of the form: VAR=VALUE */ @@ -624,8 +625,37 @@ win32_spawn (const char *executable, cmdline = argv_to_cmdline (argv); if (!cmdline) goto exit; - - /* Create the child process. */ + /* If cmdline is too large, CreateProcess will fail with a bad + 'No such file or directory' error. Try passing it through a + temporary response file instead. */ + if (strlen (cmdline) > 32767) + { + char *response_file = make_temp_file (""); + /* Register the file for deletion by pex_free. */ + ++obj->remove_count; + obj->remove = XRESIZEVEC (char *, obj->remove, obj->remove_count); + obj->remove[obj->remove_count - 1] = response_file; + int fd = pex_win32_open_write (obj, response_file, 0, 0); + if (fd == -1) + goto exit; + FILE *f = pex_win32_fdopenw (obj, fd, 0); + /* Don't write argv[0] (program name) to the response file. */ + if (writeargv (&argv[1], f)) + { + fclose (f); + goto exit; + } + fclose (f); /* Also closes fd and the underlying OS handle. */ + char *response_arg = concat ("@", response_file, NULL); + char *response_argv[3] = {argv[0], response_arg, NULL}; + free (cmdline); + cmdline = argv_to_cmdline (response_argv); + free (response_arg); + if (!cmdline) + goto exit; + } + + /* Create the child process. */ if (CreateProcess (full_executable, cmdline, /*lpProcessAttributes=*/NULL, /*lpThreadAttributes=*/NULL, @@ -645,7 +675,7 @@ win32_spawn (const char *executable, free (env_block); free (cmdline); free (full_executable); - + return pid; } @@ -653,7 +683,8 @@ win32_spawn (const char *executable, This function is called as a fallback if win32_spawn fails. */ static pid_t -spawn_script (const char *executable, char *const *argv, +spawn_script (struct pex_obj *obj, + const char *executable, char *const *argv, char* const *env, DWORD dwCreationFlags, LPSTARTUPINFO si, @@ -703,20 +734,20 @@ spawn_script (const char *executable, char *const *argv, executable = strrchr (executable1, '\\') + 1; if (!executable) executable = executable1; - pid = win32_spawn (executable, TRUE, argv, env, + pid = win32_spawn (obj, executable, TRUE, argv, env, dwCreationFlags, si, pi); #else if (strchr (executable1, '\\') == NULL) - pid = win32_spawn (executable1, TRUE, argv, env, + pid = win32_spawn (obj, executable1, TRUE, argv, env, dwCreationFlags, si, pi); else if (executable1[0] != '\\') - pid = win32_spawn (executable1, FALSE, argv, env, + pid = win32_spawn (obj, executable1, FALSE, argv, env, dwCreationFlags, si, pi); else { const char *newex = mingw_rootify (executable1); *avhere = newex; - pid = win32_spawn (newex, FALSE, argv, env, + pid = win32_spawn (obj, newex, FALSE, argv, env, dwCreationFlags, si, pi); if (executable1 != newex) free ((char *) newex); @@ -726,7 +757,7 @@ spawn_script (const char *executable, char *const *argv, if (newex != executable1) { *avhere = newex; - pid = win32_spawn (newex, FALSE, argv, env, + pid = win32_spawn (obj, newex, FALSE, argv, env, dwCreationFlags, si, pi); free ((char *) newex); } @@ -745,7 +776,7 @@ spawn_script (const char *executable, char *const *argv, /* Execute a child. */ static pid_t -pex_win32_exec_child (struct pex_obj *obj ATTRIBUTE_UNUSED, int flags, +pex_win32_exec_child (struct pex_obj *obj, int flags, const char *executable, char * const * argv, char* const* env, int in, int out, int errdes, @@ -841,10 +872,10 @@ pex_win32_exec_child (struct pex_obj *obj ATTRIBUTE_UNUSED, int flags, si.hStdError = stderr_handle; /* Create the child process. */ - pid = win32_spawn (executable, (flags & PEX_SEARCH) != 0, + pid = win32_spawn (obj, executable, (flags & PEX_SEARCH) != 0, argv, env, dwCreationFlags, &si, &pi); if (pid == (pid_t) -1) - pid = spawn_script (executable, argv, env, dwCreationFlags, + pid = spawn_script (obj, executable, argv, env, dwCreationFlags, &si, &pi); if (pid == (pid_t) -1) { -- 2.30.2