Received: (at 55937) by debbugs.gnu.org; 15 Jun 2022 20:32:33 +0000 From debbugs-submit-bounces <at> debbugs.gnu.org Wed Jun 15 16:32:33 2022 Received: from localhost ([127.0.0.1]:39979 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>) id 1o1Zgm-0000gR-Td for submit <at> debbugs.gnu.org; Wed, 15 Jun 2022 16:32:33 -0400 Received: from mail-pl1-f178.google.com ([209.85.214.178]:45051) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from <alan.rosenthal@HIDDEN>) id 1o1Zgj-0000g7-Fu for 55937 <at> debbugs.gnu.org; Wed, 15 Jun 2022 16:32:31 -0400 Received: by mail-pl1-f178.google.com with SMTP id h1so11335005plf.11 for <55937 <at> debbugs.gnu.org>; Wed, 15 Jun 2022 13:32:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=No1BIIALLYJqWzMWIcEliAoustS8/lVIOWBGXLnnugQ=; b=dhyqGcNmjXgTp0wI7uOikOXfBOvk1YoRSnfHxvQamHftmkInajV6XgrotkQxx6hgGa gQ6ohxYpNQY8p75iICGDqGh0vqJquA7j5jXum+PaYWzIzENfh9zHU95YjVwoaRGJuSeg ImIPz03Xyocm5Z23WOsf1FqkSAMe7VtgoFuo8truLWmBBhma+njCQxqB6/k1kKEO/mIZ xUL7dGVXAgTDd/jXbn6AigR+17Q+DtKzkjRK3Y0E3nckIIP0gSv+ypKTCs+bHvzNTPsq 1wyykA8nIR7j8yufvXGuRPJpJUt5wrAJgReXZ5z2B53DyiM6F9Q3ran07Jce1+vUlcPE S8AQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=No1BIIALLYJqWzMWIcEliAoustS8/lVIOWBGXLnnugQ=; b=2LgBeu5wZPA1zcEVgD6l0b0EllSgVaLsr3EQf3QgvjlxyQ6coCWqoS4s4wdYS75LwB j/eROGSi/jlSeRQhd/WWPvSF49hbCU3Hz5EdwnSfdwsdutB4rIQnT2NbdZ53CY9ZdSZi n7ZXOgtCCLt1sPtUq4/CkuFsWafeKXOvhGI9Wy525umuBqqimYazPfxUkBSVa0EV1Rqz i2hL7hkyk+mKhoDd2fPrHfui/ZHg0CdriDtwPBZIql+XiXzJiKCXpHH11m2kF13Psmlz KjTYuSEqeuYeku29naqLxg5nARfpBVLlZWZ/rzAvbuQwGdFqVPlt/wKgbu+EU9TXOCu/ DfGg== X-Gm-Message-State: AJIora+QxuWp7gihy5Temcle4Ht0OLPY/XIvN0qj3y9NpacHIGAGVdDn 35X3lqaLgsoYiq8bXqyc3BMSAzXQc1DwX8rlUzQ= X-Google-Smtp-Source: AGRyM1uAaz4p3LwX+yrifUpA2rkMeczC4InaHcm6+fcNSqzFe6r+55WP16UWQoCiL3SdjcPPRzTNKOEc1c/MVmCt06w= X-Received: by 2002:a17:903:2645:b0:167:92f1:15c0 with SMTP id je5-20020a170903264500b0016792f115c0mr1286905plb.100.1655325143449; Wed, 15 Jun 2022 13:32:23 -0700 (PDT) MIME-Version: 1.0 References: <CABEWFW8x_Th-O0TdVTNi4fuordVvEZCFPiVqPuUnqQDRrM_OHQ@HIDDEN> <CABEWFW9+oseQjHuGAhVLm9uGeDXdziOTgiKMTb4gD-guoz3-pA@HIDDEN> <CABEWFW-Cb-8k4TrS6PERny7K2uM0tcjNYshi2MH2PYovvxUS4Q@HIDDEN> <d473fbc7-d612-70c8-9903-25d43ea84576@HIDDEN> In-Reply-To: <d473fbc7-d612-70c8-9903-25d43ea84576@HIDDEN> From: Alan Rosenthal <alan.rosenthal@HIDDEN> Date: Wed, 15 Jun 2022 16:31:47 -0400 Message-ID: <CABEWFW9iJZ3edgRrWVN0=5RuMDrbAUM-uA+QqzZ1at=EKO+-2w@HIDDEN> Subject: Re: bug#55937: [PATCH] touch: create parent directories if needed To: Paul Eggert <eggert@HIDDEN> Content-Type: multipart/alternative; boundary="00000000000029c4ab05e1826b4f" X-Spam-Score: -0.0 (/) X-Debbugs-Envelope-To: 55937 Cc: 55937 <at> debbugs.gnu.org X-BeenThere: debbugs-submit <at> debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: <debbugs-submit.debbugs.gnu.org> List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe> List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/> List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org> List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help> List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe> Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org> X-Spam-Score: -1.0 (-) --00000000000029c4ab05e1826b4f Content-Type: text/plain; charset="UTF-8" Thanks for taking the time to review my patch. I agree with you that this change is not strictly required. It's more of a nice to have / ergonomic improvement to the existing touch interface. There are several StackOverflow posts that ask for this very feature: https://unix.stackexchange.com/q/63098 & https://unix.stackexchange.com/q/305844 Below is the help text for touch: > Update the access and modification times of each FILE to the current time. > A FILE argument that does not exist is created empty, unless -c or -h is supplied. I was surprised to learn there was no existing flag that would allow directory creation when a file and its directories do not exist. Currently if directories do not exist, the command fails. I would go as far to argue that creating a file also implies creating any required directories, since directories must exist before we can create said file. I also agree with David Hilton's recommendation that we should not change the default behavior of touch, like in my first patch, but rather add an opt-in flag for this behavior. Thank you for reading my reply and I look forward to your future feedback. On Tue, Jun 14, 2022 at 10:37 PM Paul Eggert <eggert@HIDDEN> wrote: > On 6/14/22 19:20, Alan Rosenthal wrote: > > `touch -p a/b/c/d/e` will now be the same as running: > > `mkdir -p a/b/c/d && touch a/b/c/d/e`. > > I don't see how this useful enough to merit a change, since one can > achieve the effect of the proposed "touch -p" with the already-existing > "mkdir -p" followed by plain "touch". mkdir -p already exists and should > work everywhere that's POSIX-compatible. We don't need -p for other > commands that create files (e.g., cp, mv, ln); what's special about > 'touch'? > > --00000000000029c4ab05e1826b4f Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable <div dir=3D"ltr">Thanks for taking the time to review my patch.<div><br></d= iv><div>I agree with you that this change is not strictly required. It'= s more of a nice to have / ergonomic=C2=A0improvement=C2=A0to the existing = touch interface.</div><div><br></div><div>There are several StackOverflow p= osts that ask for this very feature: <a href=3D"https://unix.stackexchange.= com/q/63098" target=3D"_blank">https://unix.stackexchange.com/q/63098</a> &= amp;=C2=A0<a href=3D"https://unix.stackexchange.com/q/305844" target=3D"_bl= ank">https://unix.stackexchange.com/q/305844</a></div><div><br></div><div>B= elow is the help text for touch:</div><div>> Update the access and modif= ication times of each FILE to the current time.<br>> A FILE argument tha= t does not exist is created empty, unless -c or -h is supplied.<br></div><d= iv><br></div><div>I was surprised to learn there was no existing=C2=A0flag = that would allow directory creation when a file and its directories do not = exist. Currently if directories do not exist, the command fails. I would go= as far to argue that creating a file also implies creating any required=C2= =A0directories, since directories must exist before we can create said file= .</div><div><br></div><div>I also agree with=C2=A0David Hilton's recomm= endation that we should not change the default behavior of touch, like in m= y first patch, but rather add an opt-in flag for this behavior.</div><div><= br></div><div>Thank you for reading my reply and I look forward to your fut= ure feedback.</div></div><br><div class=3D"gmail_quote"><div dir=3D"ltr" cl= ass=3D"gmail_attr">On Tue, Jun 14, 2022 at 10:37 PM Paul Eggert <<a href= =3D"mailto:eggert@HIDDEN" target=3D"_blank">eggert@HIDDEN</a>>= wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px = 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On 6/14/= 22 19:20, Alan Rosenthal wrote:<br> > `touch -p a/b/c/d/e` will now be the same as running:<br> > `mkdir -p a/b/c/d && touch a/b/c/d/e`.<br> <br> I don't see how this useful enough to merit a change, since one can <br= > achieve the effect of the proposed "touch -p" with the already-ex= isting <br> "mkdir -p" followed by plain "touch". mkdir -p already = exists and should <br> work everywhere that's POSIX-compatible. We don't need -p for other= <br> commands that create files (e.g., cp, mv, ln); what's special about = 9;touch'?<br> <br> </blockquote></div> --00000000000029c4ab05e1826b4f--
bug-coreutils@HIDDEN
:bug#55937
; Package coreutils
.
Full text available.Received: (at 55937) by debbugs.gnu.org; 15 Jun 2022 02:37:52 +0000 From debbugs-submit-bounces <at> debbugs.gnu.org Tue Jun 14 22:37:52 2022 Received: from localhost ([127.0.0.1]:36190 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>) id 1o1Iul-0002Lx-SS for submit <at> debbugs.gnu.org; Tue, 14 Jun 2022 22:37:52 -0400 Received: from zimbra.cs.ucla.edu ([131.179.128.68]:38522) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from <eggert@HIDDEN>) id 1o1Iuj-0002Li-9f for 55937 <at> debbugs.gnu.org; Tue, 14 Jun 2022 22:37:50 -0400 Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id F1C651601F1; Tue, 14 Jun 2022 19:37:42 -0700 (PDT) Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id cI9MN8UyghAL; Tue, 14 Jun 2022 19:37:42 -0700 (PDT) Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 562F81601F2; Tue, 14 Jun 2022 19:37:42 -0700 (PDT) X-Virus-Scanned: amavisd-new at zimbra.cs.ucla.edu Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id gC_cITtS74t5; Tue, 14 Jun 2022 19:37:42 -0700 (PDT) Received: from [100.115.92.201] (ip72-206-2-24.fv.ks.cox.net [72.206.2.24]) by zimbra.cs.ucla.edu (Postfix) with ESMTPSA id 0CB301601F1; Tue, 14 Jun 2022 19:37:41 -0700 (PDT) Message-ID: <d473fbc7-d612-70c8-9903-25d43ea84576@HIDDEN> Date: Tue, 14 Jun 2022 21:37:36 -0500 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.10.0 Subject: Re: bug#55937: [PATCH] touch: create parent directories if needed Content-Language: en-US To: Alan Rosenthal <alan.rosenthal@HIDDEN> References: <CABEWFW8x_Th-O0TdVTNi4fuordVvEZCFPiVqPuUnqQDRrM_OHQ@HIDDEN> <CABEWFW9+oseQjHuGAhVLm9uGeDXdziOTgiKMTb4gD-guoz3-pA@HIDDEN> <CABEWFW-Cb-8k4TrS6PERny7K2uM0tcjNYshi2MH2PYovvxUS4Q@HIDDEN> From: Paul Eggert <eggert@HIDDEN> In-Reply-To: <CABEWFW-Cb-8k4TrS6PERny7K2uM0tcjNYshi2MH2PYovvxUS4Q@HIDDEN> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 55937 Cc: 55937 <at> debbugs.gnu.org X-BeenThere: debbugs-submit <at> debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: <debbugs-submit.debbugs.gnu.org> List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe> List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/> List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org> List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help> List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe> Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org> X-Spam-Score: -3.3 (---) On 6/14/22 19:20, Alan Rosenthal wrote: > `touch -p a/b/c/d/e` will now be the same as running: > `mkdir -p a/b/c/d && touch a/b/c/d/e`. I don't see how this useful enough to merit a change, since one can achieve the effect of the proposed "touch -p" with the already-existing "mkdir -p" followed by plain "touch". mkdir -p already exists and should work everywhere that's POSIX-compatible. We don't need -p for other commands that create files (e.g., cp, mv, ln); what's special about 'touch'?
bug-coreutils@HIDDEN
:bug#55937
; Package coreutils
.
Full text available.Received: (at submit) by debbugs.gnu.org; 15 Jun 2022 00:21:28 +0000 From debbugs-submit-bounces <at> debbugs.gnu.org Tue Jun 14 20:21:28 2022 Received: from localhost ([127.0.0.1]:36080 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>) id 1o1Gml-0007F4-7a for submit <at> debbugs.gnu.org; Tue, 14 Jun 2022 20:21:28 -0400 Received: from lists.gnu.org ([209.51.188.17]:56614) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from <alan.rosenthal@HIDDEN>) id 1o1Gmg-0007Et-Q3 for submit <at> debbugs.gnu.org; Tue, 14 Jun 2022 20:21:26 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:50114) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from <alan.rosenthal@HIDDEN>) id 1o1Gmf-0006Rs-U8 for bug-coreutils@HIDDEN; Tue, 14 Jun 2022 20:21:22 -0400 Received: from mail-pf1-x42b.google.com ([2607:f8b0:4864:20::42b]:34682) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from <alan.rosenthal@HIDDEN>) id 1o1Gmd-0004i3-01 for bug-coreutils@HIDDEN; Tue, 14 Jun 2022 20:21:21 -0400 Received: by mail-pf1-x42b.google.com with SMTP id c196so9988878pfb.1 for <bug-coreutils@HIDDEN>; Tue, 14 Jun 2022 17:21:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=mime-version:references:in-reply-to:from:date:message-id:subject:to; bh=9mh7EDG3rRA7Ur9x2wdwN4CgkpPNDGFKKJq2yiPl9W4=; b=p8RNqvzEfOrLsCswehIn07oXJaTpsmaMKaLCidxqJxJyEveKwuK1bZkxgqT3sUKLST +zGH/03rV885tjyHoYXcj72T//T4oo87xhViSs4kdaYjSVwAjaxyuJ4+lAma87yJke9Q DI8maRs8PF2iwHcEJ3H2YF5a1Jm4N2c5KLNwyTV3Bir1DNV/EX7TGQTW5Drz1OPCM7oh 87hiOLmN6eE3Bz+CLzX25gA8Np/DfKqf04VOmdFT3Plm6e5NtVicb8DxAw52yYKngewZ JsU9OIE0oC9CJk4pi94GeteE8xcSpGMHK0R40fHMedOPWpgAomUnhLiLQ91P2pGcfuer JsjQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to; bh=9mh7EDG3rRA7Ur9x2wdwN4CgkpPNDGFKKJq2yiPl9W4=; b=a7y5mDmYrnjgc05Gpdh2tWVY1DMmcj/9qUeccgs4Z/gMCVbveUXp1lfNH1tP6L5EEb BepFsKnESmdE0KJg0Mky3tpJLtGIMZ008C+fkK6mJzo88xJUJY122h5tNENFgDbQyQRp yYePcD5rk1L8dXCDzWFtv6/+faMIh2X17DrWLnCGRQ57y7lrPdgAdewGZV6M4CaRgSbM ez0VURRbTiaCsxv0/1HbHurq48TmrlomuRx12AHxcogXSzh0hwSerQdd+Nrqw0TF1bvP 2NAbiQZAZi6UGJ/Ow7kpTMt4ZoDwww910CxvqNWe3+935yjJUfD/YaSOMBR+k/kdY2H6 qcoA== X-Gm-Message-State: AJIora9CxdI+IeLd29PEp+cbVMLmn8xONv7sre5t3oxhmdaArJ8BF9uV qJy1ZszUxG7bk9y0enNWjXu6NdCRO4yq+NIE71KHDJ/kVp4= X-Google-Smtp-Source: AGRyM1vwbm6tvJOj4EDvb17OeYeNHv+pZ9NYA7np1J7TaZvfS9HXUwDAiDOiGU8QPSYtmeQj2koulrd27CWxu6t6AIY= X-Received: by 2002:a63:7946:0:b0:408:c6ac:939b with SMTP id u67-20020a637946000000b00408c6ac939bmr573737pgc.349.1655252476279; Tue, 14 Jun 2022 17:21:16 -0700 (PDT) MIME-Version: 1.0 References: <CABEWFW8x_Th-O0TdVTNi4fuordVvEZCFPiVqPuUnqQDRrM_OHQ@HIDDEN> <CABEWFW9+oseQjHuGAhVLm9uGeDXdziOTgiKMTb4gD-guoz3-pA@HIDDEN> In-Reply-To: <CABEWFW9+oseQjHuGAhVLm9uGeDXdziOTgiKMTb4gD-guoz3-pA@HIDDEN> From: Alan Rosenthal <alan.rosenthal@HIDDEN> Date: Tue, 14 Jun 2022 20:20:40 -0400 Message-ID: <CABEWFW-Cb-8k4TrS6PERny7K2uM0tcjNYshi2MH2PYovvxUS4Q@HIDDEN> Subject: Re: [PATCH] touch: create parent directories if needed To: bug-coreutils@HIDDEN Content-Type: multipart/alternative; boundary="000000000000dcbf2205e1717f1f" Received-SPF: pass client-ip=2607:f8b0:4864:20::42b; envelope-from=alan.rosenthal@HIDDEN; helo=mail-pf1-x42b.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-Spam-Score: -1.3 (-) X-Debbugs-Envelope-To: submit X-BeenThere: debbugs-submit <at> debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: <debbugs-submit.debbugs.gnu.org> List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe> List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/> List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org> List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help> List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe> Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org> X-Spam-Score: -2.3 (--) --000000000000dcbf2205e1717f1f Content-Type: text/plain; charset="UTF-8" `touch -p a/b/c/d/e` will now be the same as running: `mkdir -p a/b/c/d && touch a/b/c/d/e`. Added an option -p/--create-dirs to create any required directories. Default behavior remains the same. --- src/touch.c | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/src/touch.c b/src/touch.c index 21c247d0b..543f92b41 100644 --- a/src/touch.c +++ b/src/touch.c @@ -28,10 +28,12 @@ #include "die.h" #include "error.h" #include "fd-reopen.h" +#include "mkancesdirs.h" #include "parse-datetime.h" #include "posixtm.h" #include "posixver.h" #include "quote.h" +#include "savewd.h" #include "stat-time.h" #include "utimens.h" @@ -55,6 +57,9 @@ static int change_times; /* (-c) If true, don't create if not already there. */ static bool no_create; +/* (-p) If true, create directories if not already there. */ +static bool create_dirs; + /* (-r) If true, use times from a reference file. */ static bool use_ref; @@ -88,6 +93,7 @@ static struct option const longopts[] = {"date", required_argument, NULL, 'd'}, {"reference", required_argument, NULL, 'r'}, {"no-dereference", no_argument, NULL, 'h'}, + {"create-dirs", no_argument, NULL, 'p'}, {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, {NULL, 0, NULL, 0} @@ -116,6 +122,14 @@ get_reldate (struct timespec *result, die (EXIT_FAILURE, 0, _("invalid date format %s"), quote (flex_date)); } +/* Create directory, called by mkancesdirs(). */ + +static int +make_dir(char const * file, char const * component, void * arg) +{ + return mkdir(component, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); +} + /* Update the time of file FILE according to the options given. Return true if successful. */ @@ -130,6 +144,25 @@ touch (char const *file) fd = STDOUT_FILENO; else if (! (no_create || no_dereference)) { + if (create_dirs) + { + struct savewd wd; + savewd_init(&wd); + ptrdiff_t ret = mkancesdirs((char*) file, &wd, make_dir, NULL); + if (ret == -1) + { + error (0, open_errno, _("cannot mkdir %s"), quoteaf (file)); + return false; + } + int r = savewd_restore(&wd, 0); + if (r < 0) + { + error (0, open_errno, _("cannot mkdir %s"), quoteaf (file)); + return false; + } + savewd_finish(&wd); + } + /* Try to open FILE, creating it if necessary. */ fd = fd_reopen (STDIN_FILENO, file, O_WRONLY | O_CREAT | O_NONBLOCK | O_NOCTTY, MODE_RW_UGO); @@ -240,6 +273,7 @@ change the times of the file associated with standard output.\n\ -m change only the modification time\n\ "), stdout); fputs (_("\ + -p, --create-dirs create any required parent directories\n\ -r, --reference=FILE use this file's times instead of current time\n\ -t STAMP use [[CC]YY]MMDDhhmm[.ss] instead of current time\n\ --time=WORD change the specified time:\n\ @@ -276,7 +310,7 @@ main (int argc, char **argv) change_times = 0; no_create = use_ref = false; - while ((c = getopt_long (argc, argv, "acd:fhmr:t:", longopts, NULL)) != -1) + while ((c = getopt_long (argc, argv, "acd:fhmpr:t:", longopts, NULL)) != -1) { switch (c) { @@ -303,6 +337,10 @@ main (int argc, char **argv) change_times |= CH_MTIME; break; + case 'p': + create_dirs = true; + break; + case 'r': use_ref = true; ref_file = optarg; -- 2.20.1 On Mon, Jun 13, 2022 at 7:52 AM Alan Rosenthal <alan.rosenthal@HIDDEN> wrote: > `touch a/b/c/d/e` will now be the same as running `mkdir -p a/b/c/d && > touch a/b/c/d/e`. > Added an option --no-create-dirs to not create any directories. > --- > src/touch.c | 40 +++++++++++++++++++++++++++++++++++++++- > 1 file changed, 39 insertions(+), 1 deletion(-) > > diff --git a/src/touch.c b/src/touch.c > index 21c247d0b..557530f79 100644 > --- a/src/touch.c > +++ b/src/touch.c > @@ -28,10 +28,12 @@ > #include "die.h" > #include "error.h" > #include "fd-reopen.h" > +#include "mkancesdirs.h" > #include "parse-datetime.h" > #include "posixtm.h" > #include "posixver.h" > #include "quote.h" > +#include "savewd.h" > #include "stat-time.h" > #include "utimens.h" > > @@ -55,6 +57,9 @@ static int change_times; > /* (-c) If true, don't create if not already there. */ > static bool no_create; > > +/* (-c) If true, don't create directories if not already there. */ > +static bool no_create_dirs; > + > /* (-r) If true, use times from a reference file. */ > static bool use_ref; > > @@ -88,6 +93,7 @@ static struct option const longopts[] = > {"date", required_argument, NULL, 'd'}, > {"reference", required_argument, NULL, 'r'}, > {"no-dereference", no_argument, NULL, 'h'}, > + {"no-create-dirs", no_argument, NULL, 'i'}, > {GETOPT_HELP_OPTION_DECL}, > {GETOPT_VERSION_OPTION_DECL}, > {NULL, 0, NULL, 0} > @@ -116,6 +122,14 @@ get_reldate (struct timespec *result, > die (EXIT_FAILURE, 0, _("invalid date format %s"), quote (flex_date)); > } > > +/* Create directory, called by mkancesdirs(). */ > + > +static int > +make_dir(char const * file, char const * component, void * arg) > +{ > + return mkdir(component, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | > S_IXOTH); > +} > + > /* Update the time of file FILE according to the options given. > Return true if successful. */ > > @@ -130,6 +144,25 @@ touch (char const *file) > fd = STDOUT_FILENO; > else if (! (no_create || no_dereference)) > { > + if (! no_create_dirs) > + { > + struct savewd wd; > + savewd_init(&wd); > + ptrdiff_t ret = mkancesdirs((char*) file, &wd, make_dir, NULL); > + if (ret == -1) > + { > + error (0, open_errno, _("cannot mkdir %s"), quoteaf (file)); > + return false; > + } > + int r = savewd_restore(&wd, 0); > + if (r < 0) > + { > + error (0, open_errno, _("cannot mkdir %s"), quoteaf (file)); > + return false; > + } > + savewd_finish(&wd); > + } > + > /* Try to open FILE, creating it if necessary. */ > fd = fd_reopen (STDIN_FILENO, file, > O_WRONLY | O_CREAT | O_NONBLOCK | O_NOCTTY, > MODE_RW_UGO); > @@ -234,6 +267,7 @@ change the times of the file associated with standard > output.\n\ > -f (ignored)\n\ > "), stdout); > fputs (_("\ > + -i, --no-create-dirs do not create any required parent directories\n\ > -h, --no-dereference affect each symbolic link instead of any > referenced\n\ > file (useful only on systems that can change > the\n\ > timestamps of a symlink)\n\ > @@ -276,7 +310,7 @@ main (int argc, char **argv) > change_times = 0; > no_create = use_ref = false; > > - while ((c = getopt_long (argc, argv, "acd:fhmr:t:", longopts, NULL)) != > -1) > + while ((c = getopt_long (argc, argv, "acd:fhimr:t:", longopts, NULL)) > != -1) > { > switch (c) > { > @@ -299,6 +333,10 @@ main (int argc, char **argv) > no_dereference = true; > break; > > + case 'i': > + no_create_dirs = true; > + break; > + > case 'm': > change_times |= CH_MTIME; > break; > -- > 2.20.1 > > On Sun, Jun 12, 2022 at 10:05 PM Alan Rosenthal <alan.rosenthal@HIDDEN> > wrote: > >> `touch a/b/c/d/e` will now be the same as running `mkdir -p a/b/c/d && >> touch a/b/c/d/e`. >> Added an option --no-create-dirs to not create any directories. >> --- >> src/touch.c | 39 ++++++++++++++++++++++++++++++++++++++- >> 1 file changed, 38 insertions(+), 1 deletion(-) >> >> diff --git a/src/touch.c b/src/touch.c >> index 21c247d0b..9034e8797 100644 >> --- a/src/touch.c >> +++ b/src/touch.c >> @@ -28,10 +28,12 @@ >> #include "die.h" >> #include "error.h" >> #include "fd-reopen.h" >> +#include "mkancesdirs.h" >> #include "parse-datetime.h" >> #include "posixtm.h" >> #include "posixver.h" >> #include "quote.h" >> +#include "savewd.h" >> #include "stat-time.h" >> #include "utimens.h" >> >> @@ -55,6 +57,9 @@ static int change_times; >> /* (-c) If true, don't create if not already there. */ >> static bool no_create; >> >> +/* (-c) If true, don't create directories if not already there. */ >> +static bool no_create_dirs; >> + >> /* (-r) If true, use times from a reference file. */ >> static bool use_ref; >> >> @@ -88,6 +93,7 @@ static struct option const longopts[] = >> {"date", required_argument, NULL, 'd'}, >> {"reference", required_argument, NULL, 'r'}, >> {"no-dereference", no_argument, NULL, 'h'}, >> + {"no_create_dirs", no_argument, NULL, 'i'}, >> {GETOPT_HELP_OPTION_DECL}, >> {GETOPT_VERSION_OPTION_DECL}, >> {NULL, 0, NULL, 0} >> @@ -116,6 +122,14 @@ get_reldate (struct timespec *result, >> die (EXIT_FAILURE, 0, _("invalid date format %s"), quote >> (flex_date)); >> } >> >> +/* Create directory, called by mkancesdirs(). */ >> + >> +static int >> +make_dir(char const * file, char const * component, void * arg) >> +{ >> + return mkdir(component, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | >> S_IXOTH); >> +} >> + >> /* Update the time of file FILE according to the options given. >> Return true if successful. */ >> >> @@ -130,6 +144,25 @@ touch (char const *file) >> fd = STDOUT_FILENO; >> else if (! (no_create || no_dereference)) >> { >> + if (! no_create_dirs) >> + { >> + struct savewd wd; >> + savewd_init(&wd); >> + ptrdiff_t ret = mkancesdirs((char*) file, &wd, make_dir, NULL); >> + if (ret == -1) >> + { >> + error (0, open_errno, _("cannot mkdir %s"), quoteaf >> (file)); >> + return false; >> + } >> + int r = savewd_restore(&wd, 0); >> + if (r < 0) >> + { >> + error (0, open_errno, _("cannot mkdir %s"), quoteaf >> (file)); >> + return false; >> + } >> + savewd_finish(&wd); >> + } >> + >> /* Try to open FILE, creating it if necessary. */ >> fd = fd_reopen (STDIN_FILENO, file, >> O_WRONLY | O_CREAT | O_NONBLOCK | O_NOCTTY, >> MODE_RW_UGO); >> @@ -276,7 +309,7 @@ main (int argc, char **argv) >> change_times = 0; >> no_create = use_ref = false; >> >> - while ((c = getopt_long (argc, argv, "acd:fhmr:t:", longopts, NULL)) >> != -1) >> + while ((c = getopt_long (argc, argv, "acd:fhimr:t:", longopts, NULL)) >> != -1) >> { >> switch (c) >> { >> @@ -299,6 +332,10 @@ main (int argc, char **argv) >> no_dereference = true; >> break; >> >> + case 'i': >> + no_create_dirs = true; >> + break; >> + >> case 'm': >> change_times |= CH_MTIME; >> break; >> -- >> 2.20.1 >> >> --000000000000dcbf2205e1717f1f Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable <div dir=3D"ltr">`touch -p a/b/c/d/e` will now be the same as running:<br>`= mkdir -p a/b/c/d && touch a/b/c/d/e`.<br><br>Added an option -p/--c= reate-dirs to create any required directories.<br>Default behavior remains = the same.<br>---<br>=C2=A0src/touch.c | 40 ++++++++++++++++++++++++++++++++= +++++++-<br>=C2=A01 file changed, 39 insertions(+), 1 deletion(-)<br><br>di= ff --git a/src/touch.c b/src/touch.c<br>index 21c247d0b..543f92b41 100644<b= r>--- a/src/touch.c<br>+++ b/src/touch.c<br>@@ -28,10 +28,12 @@<br>=C2=A0#i= nclude "die.h"<br>=C2=A0#include "error.h"<br>=C2=A0#in= clude "fd-reopen.h"<br>+#include "mkancesdirs.h"<br>=C2= =A0#include "parse-datetime.h"<br>=C2=A0#include "posixtm.h&= quot;<br>=C2=A0#include "posixver.h"<br>=C2=A0#include "quot= e.h"<br>+#include "savewd.h"<br>=C2=A0#include "stat-ti= me.h"<br>=C2=A0#include "utimens.h"<br>=C2=A0<br>@@ -55,6 +5= 7,9 @@ static int change_times;<br>=C2=A0/* (-c) If true, don't create = if not already there. =C2=A0*/<br>=C2=A0static bool no_create;<br>=C2=A0<br= >+/* (-p) If true, create directories if not already there. =C2=A0*/<br>+st= atic bool create_dirs;<br>+<br>=C2=A0/* (-r) If true, use times from a refe= rence file. =C2=A0*/<br>=C2=A0static bool use_ref;<br>=C2=A0<br>@@ -88,6 +9= 3,7 @@ static struct option const longopts[] =3D<br>=C2=A0 =C2=A0{"dat= e", required_argument, NULL, 'd'},<br>=C2=A0 =C2=A0{"refe= rence", required_argument, NULL, 'r'},<br>=C2=A0 =C2=A0{"= no-dereference", no_argument, NULL, 'h'},<br>+ =C2=A0{"cr= eate-dirs", no_argument, NULL, 'p'},<br>=C2=A0 =C2=A0{GETOPT_H= ELP_OPTION_DECL},<br>=C2=A0 =C2=A0{GETOPT_VERSION_OPTION_DECL},<br>=C2=A0 = =C2=A0{NULL, 0, NULL, 0}<br>@@ -116,6 +122,14 @@ get_reldate (struct timesp= ec *result,<br>=C2=A0 =C2=A0 =C2=A0die (EXIT_FAILURE, 0, _("invalid da= te format %s"), quote (flex_date));<br>=C2=A0}<br>=C2=A0<br>+/* Create= directory, called by mkancesdirs(). */<br>+<br>+static int<br>+make_dir(ch= ar const * file, char const * component, void * arg)<br>+{<br>+ =C2=A0retur= n mkdir(component, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);<br>+}<= br>+<br>=C2=A0/* Update the time of file FILE according to the options give= n.<br>=C2=A0 =C2=A0 Return true if successful. =C2=A0*/<br>=C2=A0<br>@@ -13= 0,6 +144,25 @@ touch (char const *file)<br>=C2=A0 =C2=A0 =C2=A0fd =3D STDOU= T_FILENO;<br>=C2=A0 =C2=A0else if (! (no_create || no_dereference))<br>=C2= =A0 =C2=A0 =C2=A0{<br>+ =C2=A0 =C2=A0 =C2=A0if (create_dirs)<br>+ =C2=A0 = =C2=A0 =C2=A0 =C2=A0{<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0struct savewd = wd;<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0savewd_init(&wd);<br>+ =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ptrdiff_t ret =3D mkancesdirs((char*) file, = &wd, make_dir, NULL);<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (ret = =3D=3D -1)<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{<br>+ =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0error (0, open_errno, _("cannot = mkdir %s"), quoteaf (file));<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0return false;<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}<= br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0int r =3D savewd_restore(&wd, 0)= ;<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (r < 0)<br>+ =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0{<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0error (0, open_errno, _("cannot mkdir %s"), quoteaf (file)= );<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return false;<br>+ = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0savewd_finish(&wd);<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0}<br>+<br>= =C2=A0 =C2=A0 =C2=A0 =C2=A0/* Try to open FILE, creating it if necessary. = =C2=A0*/<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0fd =3D fd_reopen (STDIN_FILENO, file= ,<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0O_WRONLY | O_CREAT | O_NONBLOCK | O_NOCTTY, MODE_RW_UGO);<br>@= @ -240,6 +273,7 @@ change the times of the file associated with standard ou= tput.\n\<br>=C2=A0 =C2=A0-m =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 change only the modification time\n\<br>=C2=A0&quo= t;), stdout);<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0fputs (_("\<br>+ =C2=A0-p,= --create-dirs =C2=A0 =C2=A0 =C2=A0create any required parent directories\n= \<br>=C2=A0 =C2=A0-r, --reference=3DFILE =C2=A0 use this file's times i= nstead of current time\n\<br>=C2=A0 =C2=A0-t STAMP =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 use [[CC]YY]MMDDhhmm[.ss] instead of current time\= n\<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0--time=3DWORD =C2=A0 =C2=A0 =C2=A0 =C2=A0c= hange the specified time:\n\<br>@@ -276,7 +310,7 @@ main (int argc, char **= argv)<br>=C2=A0 =C2=A0change_times =3D 0;<br>=C2=A0 =C2=A0no_create =3D use= _ref =3D false;<br>=C2=A0<br>- =C2=A0while ((c =3D getopt_long (argc, argv,= "acd:fhmr:t:", longopts, NULL)) !=3D -1)<br>+ =C2=A0while ((c = =3D getopt_long (argc, argv, "acd:fhmpr:t:", longopts, NULL)) != =3D -1)<br>=C2=A0 =C2=A0 =C2=A0{<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0switch (c)<b= r>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{<br>@@ -303,6 +337,10 @@ main (int arg= c, char **argv)<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0change_times |= =3D CH_MTIME;<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break;<br>=C2=A0<= br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0case 'p':<br>+ =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0create_dirs =3D true;<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= break;<br>+<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case 'r':<br>=C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0use_ref =3D true;<br>=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0ref_file =3D optarg;<br>-- <br>2.20.1<br><br></d= iv><br><div class=3D"gmail_quote"><div dir=3D"ltr" class=3D"gmail_attr">On = Mon, Jun 13, 2022 at 7:52 AM Alan Rosenthal <<a href=3D"mailto:alan.rose= nthal@HIDDEN">alan.rosenthal@HIDDEN</a>> wrote:<br></div><blockquo= te class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px = solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr">`touch a/b/c/d/e`= will now be the same as running `mkdir -p a/b/c/d &&<br>touch a/b/= c/d/e`.<br>Added an option --no-create-dirs to not create any directories.<= br>---<br>=C2=A0src/touch.c | 40 +++++++++++++++++++++++++++++++++++++++-<b= r>=C2=A01 file changed, 39 insertions(+), 1 deletion(-)<br><br>diff --git a= /src/touch.c b/src/touch.c<br>index 21c247d0b..557530f79 100644<br>--- a/sr= c/touch.c<br>+++ b/src/touch.c<br>@@ -28,10 +28,12 @@<br>=C2=A0#include &qu= ot;die.h"<br>=C2=A0#include "error.h"<br>=C2=A0#include &quo= t;fd-reopen.h"<br>+#include "mkancesdirs.h"<br>=C2=A0#includ= e "parse-datetime.h"<br>=C2=A0#include "posixtm.h"<br>= =C2=A0#include "posixver.h"<br>=C2=A0#include "quote.h"= <br>+#include "savewd.h"<br>=C2=A0#include "stat-time.h"= ;<br>=C2=A0#include "utimens.h"<br>=C2=A0<br>@@ -55,6 +57,9 @@ st= atic int change_times;<br>=C2=A0/* (-c) If true, don't create if not al= ready there. =C2=A0*/<br>=C2=A0static bool no_create;<br>=C2=A0<br>+/* (-c)= If true, don't create directories if not already there. =C2=A0*/<br>+s= tatic bool no_create_dirs;<br>+<br>=C2=A0/* (-r) If true, use times from a = reference file. =C2=A0*/<br>=C2=A0static bool use_ref;<br>=C2=A0<br>@@ -88,= 6 +93,7 @@ static struct option const longopts[] =3D<br>=C2=A0 =C2=A0{"= ;date", required_argument, NULL, 'd'},<br>=C2=A0 =C2=A0{"= reference", required_argument, NULL, 'r'},<br>=C2=A0 =C2=A0{&q= uot;no-dereference", no_argument, NULL, 'h'},<br>+ =C2=A0{&quo= t;no-create-dirs", no_argument, NULL, 'i'},<br>=C2=A0 =C2=A0{G= ETOPT_HELP_OPTION_DECL},<br>=C2=A0 =C2=A0{GETOPT_VERSION_OPTION_DECL},<br>= =C2=A0 =C2=A0{NULL, 0, NULL, 0}<br>@@ -116,6 +122,14 @@ get_reldate (struct= timespec *result,<br>=C2=A0 =C2=A0 =C2=A0die (EXIT_FAILURE, 0, _("inv= alid date format %s"), quote (flex_date));<br>=C2=A0}<br>=C2=A0<br>+/*= Create directory, called by mkancesdirs(). */<br>+<br>+static int<br>+make= _dir(char const * file, char const * component, void * arg)<br>+{<br>+ =C2= =A0return mkdir(component, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)= ;<br>+}<br>+<br>=C2=A0/* Update the time of file FILE according to the opti= ons given.<br>=C2=A0 =C2=A0 Return true if successful. =C2=A0*/<br>=C2=A0<b= r>@@ -130,6 +144,25 @@ touch (char const *file)<br>=C2=A0 =C2=A0 =C2=A0fd = =3D STDOUT_FILENO;<br>=C2=A0 =C2=A0else if (! (no_create || no_dereference)= )<br>=C2=A0 =C2=A0 =C2=A0{<br>+ =C2=A0 =C2=A0 =C2=A0if (! no_create_dirs)<b= r>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0{<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0str= uct savewd wd;<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0savewd_init(&wd);= <br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ptrdiff_t ret =3D mkancesdirs((char= *) file, &wd, make_dir, NULL);<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0i= f (ret =3D=3D -1)<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{<br>+ =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0error (0, open_errno, _("= cannot mkdir %s"), quoteaf (file));<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0return false;<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0}<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0int r =3D savewd_restore(&am= p;wd, 0);<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (r < 0)<br>+ =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0error (0, open_errno, _("cannot mkdir %s"), quoteaf= (file));<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return false= ;<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}<br>+ =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0savewd_finish(&wd);<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0}<br>= +<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0/* Try to open FILE, creating it if necessa= ry. =C2=A0*/<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0fd =3D fd_reopen (STDIN_FILENO, = file,<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0O_WRONLY | O_CREAT | O_NONBLOCK | O_NOCTTY, MODE_RW_UGO);<= br>@@ -234,6 +267,7 @@ change the times of the file associated with standar= d output.\n\<br>=C2=A0 =C2=A0-f =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 (ignored)\n\<br>=C2=A0"), stdout);<br>=C2= =A0 =C2=A0 =C2=A0 =C2=A0fputs (_("\<br>+ =C2=A0-i, --no-create-dirs = =C2=A0 do not create any required parent directories\n\<br>=C2=A0 =C2=A0-h,= --no-dereference =C2=A0 affect each symbolic link instead of any reference= d\n\<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 file (useful only on systems that can change the\n= \<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 timestamps of a symlink)\n\<br>@@ -276,7 +310,7 @@ mai= n (int argc, char **argv)<br>=C2=A0 =C2=A0change_times =3D 0;<br>=C2=A0 =C2= =A0no_create =3D use_ref =3D false;<br>=C2=A0<br>- =C2=A0while ((c =3D geto= pt_long (argc, argv, "acd:fhmr:t:", longopts, NULL)) !=3D -1)<br>= + =C2=A0while ((c =3D getopt_long (argc, argv, "acd:fhimr:t:", lo= ngopts, NULL)) !=3D -1)<br>=C2=A0 =C2=A0 =C2=A0{<br>=C2=A0 =C2=A0 =C2=A0 = =C2=A0switch (c)<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{<br>@@ -299,6 +333,1= 0 @@ main (int argc, char **argv)<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0no_dereference =3D true;<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0bre= ak;<br>=C2=A0<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0case 'i':<br>+ =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0no_create_dirs =3D true;<br>+ =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0break;<br>+<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case '= ;m':<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0change_times |=3D CH_M= TIME;<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break;<br><div>-- <br>2.2= 0.1<br></div></div><br><div class=3D"gmail_quote"><div dir=3D"ltr" class=3D= "gmail_attr">On Sun, Jun 12, 2022 at 10:05 PM Alan Rosenthal <<a href=3D= "mailto:alan.rosenthal@HIDDEN" target=3D"_blank">alan.rosenthal@HIDDEN= m</a>> wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"margin= :0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"= ><div dir=3D"ltr">`touch a/b/c/d/e` will now be the same as running `mkdir = -p a/b/c/d &&<br>touch a/b/c/d/e`.<br>Added an option --no-create-d= irs to not create any directories.<br>---<br>=C2=A0src/touch.c | 39 +++++++= +++++++++++++++++++++++++++++++-<br>=C2=A01 file changed, 38 insertions(+),= 1 deletion(-)<br><br>diff --git a/src/touch.c b/src/touch.c<br>index 21c24= 7d0b..9034e8797 100644<br>--- a/src/touch.c<br>+++ b/src/touch.c<br>@@ -28,= 10 +28,12 @@<br>=C2=A0#include "die.h"<br>=C2=A0#include "er= ror.h"<br>=C2=A0#include "fd-reopen.h"<br>+#include "mk= ancesdirs.h"<br>=C2=A0#include "parse-datetime.h"<br>=C2=A0#= include "posixtm.h"<br>=C2=A0#include "posixver.h"<br>= =C2=A0#include "quote.h"<br>+#include "savewd.h"<br>=C2= =A0#include "stat-time.h"<br>=C2=A0#include "utimens.h"= <br>=C2=A0<br>@@ -55,6 +57,9 @@ static int change_times;<br>=C2=A0/* (-c) I= f true, don't create if not already there. =C2=A0*/<br>=C2=A0static boo= l no_create;<br>=C2=A0<br>+/* (-c) If true, don't create directories if= not already there. =C2=A0*/<br>+static bool no_create_dirs;<br>+<br>=C2=A0= /* (-r) If true, use times from a reference file. =C2=A0*/<br>=C2=A0static = bool use_ref;<br>=C2=A0<br>@@ -88,6 +93,7 @@ static struct option const lon= gopts[] =3D<br>=C2=A0 =C2=A0{"date", required_argument, NULL, = 9;d'},<br>=C2=A0 =C2=A0{"reference", required_argument, NULL,= 'r'},<br>=C2=A0 =C2=A0{"no-dereference", no_argument, NU= LL, 'h'},<br>+ =C2=A0{"no_create_dirs", no_argument, NULL= , 'i'},<br>=C2=A0 =C2=A0{GETOPT_HELP_OPTION_DECL},<br>=C2=A0 =C2=A0= {GETOPT_VERSION_OPTION_DECL},<br>=C2=A0 =C2=A0{NULL, 0, NULL, 0}<br>@@ -116= ,6 +122,14 @@ get_reldate (struct timespec *result,<br>=C2=A0 =C2=A0 =C2=A0= die (EXIT_FAILURE, 0, _("invalid date format %s"), quote (flex_da= te));<br>=C2=A0}<br>=C2=A0<br>+/* Create directory, called by mkancesdirs()= . */<br>+<br>+static int<br>+make_dir(char const * file, char const * compo= nent, void * arg)<br>+{<br>+ =C2=A0return mkdir(component, S_IRWXU | S_IRGR= P | S_IXGRP | S_IROTH | S_IXOTH);<br>+}<br>+<br>=C2=A0/* Update the time of= file FILE according to the options given.<br>=C2=A0 =C2=A0 Return true if = successful. =C2=A0*/<br>=C2=A0<br>@@ -130,6 +144,25 @@ touch (char const *f= ile)<br>=C2=A0 =C2=A0 =C2=A0fd =3D STDOUT_FILENO;<br>=C2=A0 =C2=A0else if (= ! (no_create || no_dereference))<br>=C2=A0 =C2=A0 =C2=A0{<br>+ =C2=A0 =C2= =A0 =C2=A0if (! no_create_dirs)<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0{<br>+ =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0struct savewd wd;<br>+ =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0savewd_init(&wd);<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0p= trdiff_t ret =3D mkancesdirs((char*) file, &wd, make_dir, NULL);<br>+ = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (ret =3D=3D -1)<br>+ =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0{<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0error (0, open_errno, _("cannot mkdir %s"), quoteaf (file))= ;<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return false;<br>+ = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0int r =3D savewd_restore(&wd, 0);<br>+ =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0if (r < 0)<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{<br>= + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0error (0, open_errno, _(&= quot;cannot mkdir %s"), quoteaf (file));<br>+ =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0return false;<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0}<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0savewd_finish(&wd);<= br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0}<br>+<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0/* Try= to open FILE, creating it if necessary. =C2=A0*/<br>=C2=A0 =C2=A0 =C2=A0 = =C2=A0fd =3D fd_reopen (STDIN_FILENO, file,<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0O_WRONLY | O_CREAT |= O_NONBLOCK | O_NOCTTY, MODE_RW_UGO);<br>@@ -276,7 +309,7 @@ main (int argc= , char **argv)<br>=C2=A0 =C2=A0change_times =3D 0;<br>=C2=A0 =C2=A0no_creat= e =3D use_ref =3D false;<br>=C2=A0<br>- =C2=A0while ((c =3D getopt_long (ar= gc, argv, "acd:fhmr:t:", longopts, NULL)) !=3D -1)<br>+ =C2=A0whi= le ((c =3D getopt_long (argc, argv, "acd:fhimr:t:", longopts, NUL= L)) !=3D -1)<br>=C2=A0 =C2=A0 =C2=A0{<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0switch = (c)<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{<br>@@ -299,6 +332,10 @@ main (in= t argc, char **argv)<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0no_derefer= ence =3D true;<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break;<br>=C2=A0= <br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0case 'i':<br>+ =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0no_create_dirs =3D true;<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0break;<br>+<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case 'm':<br= >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0change_times |=3D CH_MTIME;<br>= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break;<br>-- <br>2.20.1<br><br></d= iv> </blockquote></div> </blockquote></div> --000000000000dcbf2205e1717f1f--
bug-coreutils@HIDDEN
:bug#55937
; Package coreutils
.
Full text available.Received: (at 55937) by debbugs.gnu.org; 13 Jun 2022 14:19:53 +0000 From debbugs-submit-bounces <at> debbugs.gnu.org Mon Jun 13 10:19:53 2022 Received: from localhost ([127.0.0.1]:60019 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>) id 1o0kv3-0002JZ-BA for submit <at> debbugs.gnu.org; Mon, 13 Jun 2022 10:19:53 -0400 Received: from mail-oa1-f50.google.com ([209.85.160.50]:39652) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from <quercus.aeternam@HIDDEN>) id 1o0jbv-0001I2-US for 55937 <at> debbugs.gnu.org; Mon, 13 Jun 2022 08:56:05 -0400 Received: by mail-oa1-f50.google.com with SMTP id 586e51a60fabf-10113b4c2b5so6574478fac.6 for <55937 <at> debbugs.gnu.org>; Mon, 13 Jun 2022 05:56:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=mime-version:from:date:message-id:subject:to; bh=ZN+JAs6D9cIXI5HPC67BUm5vB2sHWPNS/jjv8AVmJAs=; b=Rrpiuz+RFci98h+KH0WveBFAGAjWU+Zntm9Fo6G8gtdIDVgyS7pAtk8z6O9oikikFk FvBOzF1KqxPwUrc8jFGphynRoaob4LtZ7pFeeUazCYEhGuaYlBaiIeF24nTOJsoPOyWq u/DPzS7mGvuRcHaSwKMaPTFM8YKzTcokvjaqBGM3NkqFj3BREyEhZsqKtyqxA0e0uRTy D9Lu6PxynzLpOV/AgR1bgOWWt5X1AUTu3n5cntsSUUvDDtaU3P8AHUh68Lo4jxsD1nyg iHs3tKeFMDGq5HmwlVjybuIizhxhxbTMnVbY6qmeW7LLtGbcAyahShqK8mA7U2x3B6RQ iRBA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=ZN+JAs6D9cIXI5HPC67BUm5vB2sHWPNS/jjv8AVmJAs=; b=pFkJLg28RixNKnY+qQ9Bzo3DuYpiTl/yo3I8WfnPoW6HnlpKI7SpaSlkU286tPREFo ijfG8G9w7CSsCN+o4Mt8Y4hVLre5K0zanHFQOAyVibhO6nZJo3wfevJms29Enee1kI4a iXf+B6ZytWxvFAlmiebMIpiolXVKKI60Mno0JYMpy4QtFBcQ32Kc5tjTpetyZaTNm3WF 4lA78rAFc05WKlGCvvHWucUeDwpUBh8LFXkEA8VgQ4Se25DOsFFsJ+vY6I4+NCUcU8mM UKCpJoca5CS0/zf1Zyq6ej8Fi03Bx8jUF3nfTN/xPGCVhmIYb+sVXxcOPtW517HQgi2w CD+A== X-Gm-Message-State: AOAM531Wqh14wDx+N20/NSYTg0LfiOnDfh7OVWbY8Q3T2uWs1ZdR0AbD gUgi7NDXOBrHmw1Exo3bU9YHDAzvSw1Gv4Tv/aQtoCg= X-Google-Smtp-Source: ABdhPJw4+7EpeervJtPSFmS/5H/7hHwaSdSO/7dnCg6NgaizI59cU9A+xw09duDF2oat57QJbX75uP82CkBJEeOx/fc= X-Received: by 2002:a05:6870:b383:b0:e9:2fea:2148 with SMTP id w3-20020a056870b38300b000e92fea2148mr7112318oap.103.1655124957912; Mon, 13 Jun 2022 05:55:57 -0700 (PDT) MIME-Version: 1.0 From: David Hilton <david.hilton.p@HIDDEN> Date: Mon, 13 Jun 2022 06:55:31 -0600 Message-ID: <CALJCVT0zNS4=-03BPtqdYWDXLq_rWQkpNShqdfb4Di2PMvQ=Ug@HIDDEN> Subject: RE: bug#55937: [PATCH] touch: create parent directories if needed To: 55937 <at> debbugs.gnu.org Content-Type: multipart/alternative; boundary="0000000000002ce30e05e153cfb1" X-Spam-Score: -0.0 (/) X-Debbugs-Envelope-To: 55937 X-Mailman-Approved-At: Mon, 13 Jun 2022 10:19:52 -0400 X-BeenThere: debbugs-submit <at> debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: <debbugs-submit.debbugs.gnu.org> List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe> List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/> List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org> List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help> List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe> Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org> X-Spam-Score: -1.0 (-) --0000000000002ce30e05e153cfb1 Content-Type: text/plain; charset="UTF-8" I don't like this as the default behavior. If this feature is added, it should be optional, and enabled with -p, like mkdir. David --0000000000002ce30e05e153cfb1 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable <div dir=3D"ltr"><div>I don't like this as the default behavior. If thi= s feature is added, it should be optional, and enabled with -p, like mkdir.= <br></div><div><br></div><div><div dir=3D"ltr" class=3D"gmail_signature" da= ta-smartmail=3D"gmail_signature"><div dir=3D"ltr"><div>David</div></div></d= iv></div></div> --0000000000002ce30e05e153cfb1--
bug-coreutils@HIDDEN
:bug#55937
; Package coreutils
.
Full text available.Received: (at submit) by debbugs.gnu.org; 13 Jun 2022 11:53:33 +0000 From debbugs-submit-bounces <at> debbugs.gnu.org Mon Jun 13 07:53:33 2022 Received: from localhost ([127.0.0.1]:57390 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>) id 1o0idQ-0003Yc-Q8 for submit <at> debbugs.gnu.org; Mon, 13 Jun 2022 07:53:33 -0400 Received: from lists.gnu.org ([209.51.188.17]:45702) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from <alan.rosenthal@HIDDEN>) id 1o0idM-0003YR-U0 for submit <at> debbugs.gnu.org; Mon, 13 Jun 2022 07:53:31 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39628) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from <alan.rosenthal@HIDDEN>) id 1o0idM-0000NG-J1 for bug-coreutils@HIDDEN; Mon, 13 Jun 2022 07:53:28 -0400 Received: from mail-pl1-x62b.google.com ([2607:f8b0:4864:20::62b]:46777) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from <alan.rosenthal@HIDDEN>) id 1o0idK-0004aU-9I for bug-coreutils@HIDDEN; Mon, 13 Jun 2022 07:53:28 -0400 Received: by mail-pl1-x62b.google.com with SMTP id d13so4864733plh.13 for <bug-coreutils@HIDDEN>; Mon, 13 Jun 2022 04:53:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=mime-version:references:in-reply-to:from:date:message-id:subject:to; bh=qU/HxSy5SBISOP6knGBVgoQ7PP7pz/eLiGMRIcJsbmU=; b=c4e3rhHWF6sj5Cw2QOypZR2aHGMM8MvC10YqbZJJqRJXKHNl3aEgFL6/GDcdLURA3W SZqBnmFA9m38v73CA47DL7zRlfB10p/TkP5LAqzRm9GkXfVAr1A2GsTu/YfdZEKJv6Zc 4l1T8jh/u4HIlLmc0kOnfYJi9UoyKQ+dZjhE7HYs3wj+MLK14t6GMDsJsyIKs53VrLzx yLUVmy2KqrTBXvYxJpprhTC+pUQ/LC0K+0wqttJS0aoYrDRXdpl+kVYXaR1bv9QtKhrP ZHdLtMt2Y98GeMRqmgyfk6J0X/AJ5H+HLzCDeuDKxjS5iDfZIGP9ndhPIW0qsT25CByT 7JHw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to; bh=qU/HxSy5SBISOP6knGBVgoQ7PP7pz/eLiGMRIcJsbmU=; b=mt2UWa0n68cf65buuidc5eV0JYQYVbSYvURXpYCSWpKIGE+tFm5OgnyI6McfII8/2U eYRWT6wnoPNTKj/WbtV2oFklbNzD3TUNzpzVIeHXbFsKbfPcX3WuidNkFLWiLEQ8YZA2 bt4OL8nO8T5SjYIfxNeQV7R0kJfe0fFs6lJNR7du4t8IoXHUDYYvIuiQkKy0WJQLIMwq vjlVUvithG8p/f/hnocq/RddLhvfa3gy/s+NfBjoz6HOi/VVOf99KZX8DZ/iiTlGIR/Z wsTovU0HRgGnfFy1ZRR7/XSIAQpBrIL90ic454BhoeXkYB69gvBUxyno1rWRH7RCNhhh mwQQ== X-Gm-Message-State: AOAM533IDPVGIVNfzKbgCeW3mB9JKSg2P5LkFnfn1W/0vXxh8WjuRzRn h0ONk06dQjwHplshQCB+ubKPFlTlzov2cEomwiYpjAkbkBo= X-Google-Smtp-Source: ABdhPJzki8IjrZOuMuXLaJKQJnBkNMCLz0DUTnEXy2OgZqG+zCLJl3TzmKN2cfnmI9bNhz5PwKImQJDB4bNjFe1YRPs= X-Received: by 2002:a17:903:2645:b0:167:92f1:15c0 with SMTP id je5-20020a170903264500b0016792f115c0mr32758940plb.100.1655121203450; Mon, 13 Jun 2022 04:53:23 -0700 (PDT) MIME-Version: 1.0 References: <CABEWFW8x_Th-O0TdVTNi4fuordVvEZCFPiVqPuUnqQDRrM_OHQ@HIDDEN> In-Reply-To: <CABEWFW8x_Th-O0TdVTNi4fuordVvEZCFPiVqPuUnqQDRrM_OHQ@HIDDEN> From: Alan Rosenthal <alan.rosenthal@HIDDEN> Date: Mon, 13 Jun 2022 07:52:47 -0400 Message-ID: <CABEWFW9+oseQjHuGAhVLm9uGeDXdziOTgiKMTb4gD-guoz3-pA@HIDDEN> Subject: Re: [PATCH] touch: create parent directories if needed To: bug-coreutils@HIDDEN Content-Type: multipart/alternative; boundary="0000000000006458b805e152ef45" Received-SPF: pass client-ip=2607:f8b0:4864:20::62b; envelope-from=alan.rosenthal@HIDDEN; helo=mail-pl1-x62b.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-Spam-Score: -1.3 (-) X-Debbugs-Envelope-To: submit X-BeenThere: debbugs-submit <at> debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: <debbugs-submit.debbugs.gnu.org> List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe> List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/> List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org> List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help> List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe> Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org> X-Spam-Score: -2.3 (--) --0000000000006458b805e152ef45 Content-Type: text/plain; charset="UTF-8" `touch a/b/c/d/e` will now be the same as running `mkdir -p a/b/c/d && touch a/b/c/d/e`. Added an option --no-create-dirs to not create any directories. --- src/touch.c | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/src/touch.c b/src/touch.c index 21c247d0b..557530f79 100644 --- a/src/touch.c +++ b/src/touch.c @@ -28,10 +28,12 @@ #include "die.h" #include "error.h" #include "fd-reopen.h" +#include "mkancesdirs.h" #include "parse-datetime.h" #include "posixtm.h" #include "posixver.h" #include "quote.h" +#include "savewd.h" #include "stat-time.h" #include "utimens.h" @@ -55,6 +57,9 @@ static int change_times; /* (-c) If true, don't create if not already there. */ static bool no_create; +/* (-c) If true, don't create directories if not already there. */ +static bool no_create_dirs; + /* (-r) If true, use times from a reference file. */ static bool use_ref; @@ -88,6 +93,7 @@ static struct option const longopts[] = {"date", required_argument, NULL, 'd'}, {"reference", required_argument, NULL, 'r'}, {"no-dereference", no_argument, NULL, 'h'}, + {"no-create-dirs", no_argument, NULL, 'i'}, {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, {NULL, 0, NULL, 0} @@ -116,6 +122,14 @@ get_reldate (struct timespec *result, die (EXIT_FAILURE, 0, _("invalid date format %s"), quote (flex_date)); } +/* Create directory, called by mkancesdirs(). */ + +static int +make_dir(char const * file, char const * component, void * arg) +{ + return mkdir(component, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); +} + /* Update the time of file FILE according to the options given. Return true if successful. */ @@ -130,6 +144,25 @@ touch (char const *file) fd = STDOUT_FILENO; else if (! (no_create || no_dereference)) { + if (! no_create_dirs) + { + struct savewd wd; + savewd_init(&wd); + ptrdiff_t ret = mkancesdirs((char*) file, &wd, make_dir, NULL); + if (ret == -1) + { + error (0, open_errno, _("cannot mkdir %s"), quoteaf (file)); + return false; + } + int r = savewd_restore(&wd, 0); + if (r < 0) + { + error (0, open_errno, _("cannot mkdir %s"), quoteaf (file)); + return false; + } + savewd_finish(&wd); + } + /* Try to open FILE, creating it if necessary. */ fd = fd_reopen (STDIN_FILENO, file, O_WRONLY | O_CREAT | O_NONBLOCK | O_NOCTTY, MODE_RW_UGO); @@ -234,6 +267,7 @@ change the times of the file associated with standard output.\n\ -f (ignored)\n\ "), stdout); fputs (_("\ + -i, --no-create-dirs do not create any required parent directories\n\ -h, --no-dereference affect each symbolic link instead of any referenced\n\ file (useful only on systems that can change the\n\ timestamps of a symlink)\n\ @@ -276,7 +310,7 @@ main (int argc, char **argv) change_times = 0; no_create = use_ref = false; - while ((c = getopt_long (argc, argv, "acd:fhmr:t:", longopts, NULL)) != -1) + while ((c = getopt_long (argc, argv, "acd:fhimr:t:", longopts, NULL)) != -1) { switch (c) { @@ -299,6 +333,10 @@ main (int argc, char **argv) no_dereference = true; break; + case 'i': + no_create_dirs = true; + break; + case 'm': change_times |= CH_MTIME; break; -- 2.20.1 On Sun, Jun 12, 2022 at 10:05 PM Alan Rosenthal <alan.rosenthal@HIDDEN> wrote: > `touch a/b/c/d/e` will now be the same as running `mkdir -p a/b/c/d && > touch a/b/c/d/e`. > Added an option --no-create-dirs to not create any directories. > --- > src/touch.c | 39 ++++++++++++++++++++++++++++++++++++++- > 1 file changed, 38 insertions(+), 1 deletion(-) > > diff --git a/src/touch.c b/src/touch.c > index 21c247d0b..9034e8797 100644 > --- a/src/touch.c > +++ b/src/touch.c > @@ -28,10 +28,12 @@ > #include "die.h" > #include "error.h" > #include "fd-reopen.h" > +#include "mkancesdirs.h" > #include "parse-datetime.h" > #include "posixtm.h" > #include "posixver.h" > #include "quote.h" > +#include "savewd.h" > #include "stat-time.h" > #include "utimens.h" > > @@ -55,6 +57,9 @@ static int change_times; > /* (-c) If true, don't create if not already there. */ > static bool no_create; > > +/* (-c) If true, don't create directories if not already there. */ > +static bool no_create_dirs; > + > /* (-r) If true, use times from a reference file. */ > static bool use_ref; > > @@ -88,6 +93,7 @@ static struct option const longopts[] = > {"date", required_argument, NULL, 'd'}, > {"reference", required_argument, NULL, 'r'}, > {"no-dereference", no_argument, NULL, 'h'}, > + {"no_create_dirs", no_argument, NULL, 'i'}, > {GETOPT_HELP_OPTION_DECL}, > {GETOPT_VERSION_OPTION_DECL}, > {NULL, 0, NULL, 0} > @@ -116,6 +122,14 @@ get_reldate (struct timespec *result, > die (EXIT_FAILURE, 0, _("invalid date format %s"), quote (flex_date)); > } > > +/* Create directory, called by mkancesdirs(). */ > + > +static int > +make_dir(char const * file, char const * component, void * arg) > +{ > + return mkdir(component, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | > S_IXOTH); > +} > + > /* Update the time of file FILE according to the options given. > Return true if successful. */ > > @@ -130,6 +144,25 @@ touch (char const *file) > fd = STDOUT_FILENO; > else if (! (no_create || no_dereference)) > { > + if (! no_create_dirs) > + { > + struct savewd wd; > + savewd_init(&wd); > + ptrdiff_t ret = mkancesdirs((char*) file, &wd, make_dir, NULL); > + if (ret == -1) > + { > + error (0, open_errno, _("cannot mkdir %s"), quoteaf (file)); > + return false; > + } > + int r = savewd_restore(&wd, 0); > + if (r < 0) > + { > + error (0, open_errno, _("cannot mkdir %s"), quoteaf (file)); > + return false; > + } > + savewd_finish(&wd); > + } > + > /* Try to open FILE, creating it if necessary. */ > fd = fd_reopen (STDIN_FILENO, file, > O_WRONLY | O_CREAT | O_NONBLOCK | O_NOCTTY, > MODE_RW_UGO); > @@ -276,7 +309,7 @@ main (int argc, char **argv) > change_times = 0; > no_create = use_ref = false; > > - while ((c = getopt_long (argc, argv, "acd:fhmr:t:", longopts, NULL)) != > -1) > + while ((c = getopt_long (argc, argv, "acd:fhimr:t:", longopts, NULL)) > != -1) > { > switch (c) > { > @@ -299,6 +332,10 @@ main (int argc, char **argv) > no_dereference = true; > break; > > + case 'i': > + no_create_dirs = true; > + break; > + > case 'm': > change_times |= CH_MTIME; > break; > -- > 2.20.1 > > --0000000000006458b805e152ef45 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable <div dir=3D"ltr">`touch a/b/c/d/e` will now be the same as running `mkdir -= p a/b/c/d &&<br>touch a/b/c/d/e`.<br>Added an option --no-create-di= rs to not create any directories.<br>---<br>=C2=A0src/touch.c | 40 ++++++++= +++++++++++++++++++++++++++++++-<br>=C2=A01 file changed, 39 insertions(+),= 1 deletion(-)<br><br>diff --git a/src/touch.c b/src/touch.c<br>index 21c24= 7d0b..557530f79 100644<br>--- a/src/touch.c<br>+++ b/src/touch.c<br>@@ -28,= 10 +28,12 @@<br>=C2=A0#include "die.h"<br>=C2=A0#include "er= ror.h"<br>=C2=A0#include "fd-reopen.h"<br>+#include "mk= ancesdirs.h"<br>=C2=A0#include "parse-datetime.h"<br>=C2=A0#= include "posixtm.h"<br>=C2=A0#include "posixver.h"<br>= =C2=A0#include "quote.h"<br>+#include "savewd.h"<br>=C2= =A0#include "stat-time.h"<br>=C2=A0#include "utimens.h"= <br>=C2=A0<br>@@ -55,6 +57,9 @@ static int change_times;<br>=C2=A0/* (-c) I= f true, don't create if not already there. =C2=A0*/<br>=C2=A0static boo= l no_create;<br>=C2=A0<br>+/* (-c) If true, don't create directories if= not already there. =C2=A0*/<br>+static bool no_create_dirs;<br>+<br>=C2=A0= /* (-r) If true, use times from a reference file. =C2=A0*/<br>=C2=A0static = bool use_ref;<br>=C2=A0<br>@@ -88,6 +93,7 @@ static struct option const lon= gopts[] =3D<br>=C2=A0 =C2=A0{"date", required_argument, NULL, = 9;d'},<br>=C2=A0 =C2=A0{"reference", required_argument, NULL,= 'r'},<br>=C2=A0 =C2=A0{"no-dereference", no_argument, NU= LL, 'h'},<br>+ =C2=A0{"no-create-dirs", no_argument, NULL= , 'i'},<br>=C2=A0 =C2=A0{GETOPT_HELP_OPTION_DECL},<br>=C2=A0 =C2=A0= {GETOPT_VERSION_OPTION_DECL},<br>=C2=A0 =C2=A0{NULL, 0, NULL, 0}<br>@@ -116= ,6 +122,14 @@ get_reldate (struct timespec *result,<br>=C2=A0 =C2=A0 =C2=A0= die (EXIT_FAILURE, 0, _("invalid date format %s"), quote (flex_da= te));<br>=C2=A0}<br>=C2=A0<br>+/* Create directory, called by mkancesdirs()= . */<br>+<br>+static int<br>+make_dir(char const * file, char const * compo= nent, void * arg)<br>+{<br>+ =C2=A0return mkdir(component, S_IRWXU | S_IRGR= P | S_IXGRP | S_IROTH | S_IXOTH);<br>+}<br>+<br>=C2=A0/* Update the time of= file FILE according to the options given.<br>=C2=A0 =C2=A0 Return true if = successful. =C2=A0*/<br>=C2=A0<br>@@ -130,6 +144,25 @@ touch (char const *f= ile)<br>=C2=A0 =C2=A0 =C2=A0fd =3D STDOUT_FILENO;<br>=C2=A0 =C2=A0else if (= ! (no_create || no_dereference))<br>=C2=A0 =C2=A0 =C2=A0{<br>+ =C2=A0 =C2= =A0 =C2=A0if (! no_create_dirs)<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0{<br>+ =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0struct savewd wd;<br>+ =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0savewd_init(&wd);<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0p= trdiff_t ret =3D mkancesdirs((char*) file, &wd, make_dir, NULL);<br>+ = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (ret =3D=3D -1)<br>+ =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0{<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0error (0, open_errno, _("cannot mkdir %s"), quoteaf (file))= ;<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return false;<br>+ = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0int r =3D savewd_restore(&wd, 0);<br>+ =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0if (r < 0)<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{<br>= + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0error (0, open_errno, _(&= quot;cannot mkdir %s"), quoteaf (file));<br>+ =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0return false;<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0}<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0savewd_finish(&wd);<= br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0}<br>+<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0/* Try= to open FILE, creating it if necessary. =C2=A0*/<br>=C2=A0 =C2=A0 =C2=A0 = =C2=A0fd =3D fd_reopen (STDIN_FILENO, file,<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0O_WRONLY | O_CREAT |= O_NONBLOCK | O_NOCTTY, MODE_RW_UGO);<br>@@ -234,6 +267,7 @@ change the tim= es of the file associated with standard output.\n\<br>=C2=A0 =C2=A0-f =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (ignored= )\n\<br>=C2=A0"), stdout);<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0fputs (_(&quo= t;\<br>+ =C2=A0-i, --no-create-dirs =C2=A0 do not create any required paren= t directories\n\<br>=C2=A0 =C2=A0-h, --no-dereference =C2=A0 affect each sy= mbolic link instead of any referenced\n\<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 file (useful on= ly on systems that can change the\n\<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 timestamps of a sym= link)\n\<br>@@ -276,7 +310,7 @@ main (int argc, char **argv)<br>=C2=A0 =C2= =A0change_times =3D 0;<br>=C2=A0 =C2=A0no_create =3D use_ref =3D false;<br>= =C2=A0<br>- =C2=A0while ((c =3D getopt_long (argc, argv, "acd:fhmr:t:&= quot;, longopts, NULL)) !=3D -1)<br>+ =C2=A0while ((c =3D getopt_long (argc= , argv, "acd:fhimr:t:", longopts, NULL)) !=3D -1)<br>=C2=A0 =C2= =A0 =C2=A0{<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0switch (c)<br>=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0{<br>@@ -299,6 +333,10 @@ main (int argc, char **argv)<br>= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0no_dereference =3D true;<br>=C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break;<br>=C2=A0<br>+ =C2=A0 =C2=A0 =C2= =A0 =C2=A0case 'i':<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0no_creat= e_dirs =3D true;<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break;<br>+<br>=C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case 'm':<br>=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0change_times |=3D CH_MTIME;<br>=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0break;<br><div>-- <br>2.20.1<br></div></div><br><div class= =3D"gmail_quote"><div dir=3D"ltr" class=3D"gmail_attr">On Sun, Jun 12, 2022= at 10:05 PM Alan Rosenthal <<a href=3D"mailto:alan.rosenthal@HIDDEN"= >alan.rosenthal@HIDDEN</a>> wrote:<br></div><blockquote class=3D"gmai= l_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,20= 4,204);padding-left:1ex"><div dir=3D"ltr">`touch a/b/c/d/e` will now be the= same as running `mkdir -p a/b/c/d &&<br>touch a/b/c/d/e`.<br>Added= an option --no-create-dirs to not create any directories.<br>---<br>=C2=A0= src/touch.c | 39 ++++++++++++++++++++++++++++++++++++++-<br>=C2=A01 file ch= anged, 38 insertions(+), 1 deletion(-)<br><br>diff --git a/src/touch.c b/sr= c/touch.c<br>index 21c247d0b..9034e8797 100644<br>--- a/src/touch.c<br>+++ = b/src/touch.c<br>@@ -28,10 +28,12 @@<br>=C2=A0#include "die.h"<br= >=C2=A0#include "error.h"<br>=C2=A0#include "fd-reopen.h&quo= t;<br>+#include "mkancesdirs.h"<br>=C2=A0#include "parse-dat= etime.h"<br>=C2=A0#include "posixtm.h"<br>=C2=A0#include &qu= ot;posixver.h"<br>=C2=A0#include "quote.h"<br>+#include &quo= t;savewd.h"<br>=C2=A0#include "stat-time.h"<br>=C2=A0#includ= e "utimens.h"<br>=C2=A0<br>@@ -55,6 +57,9 @@ static int change_ti= mes;<br>=C2=A0/* (-c) If true, don't create if not already there. =C2= =A0*/<br>=C2=A0static bool no_create;<br>=C2=A0<br>+/* (-c) If true, don= 9;t create directories if not already there. =C2=A0*/<br>+static bool no_cr= eate_dirs;<br>+<br>=C2=A0/* (-r) If true, use times from a reference file. = =C2=A0*/<br>=C2=A0static bool use_ref;<br>=C2=A0<br>@@ -88,6 +93,7 @@ stati= c struct option const longopts[] =3D<br>=C2=A0 =C2=A0{"date", req= uired_argument, NULL, 'd'},<br>=C2=A0 =C2=A0{"reference",= required_argument, NULL, 'r'},<br>=C2=A0 =C2=A0{"no-dereferen= ce", no_argument, NULL, 'h'},<br>+ =C2=A0{"no_create_dirs= ", no_argument, NULL, 'i'},<br>=C2=A0 =C2=A0{GETOPT_HELP_OPTIO= N_DECL},<br>=C2=A0 =C2=A0{GETOPT_VERSION_OPTION_DECL},<br>=C2=A0 =C2=A0{NUL= L, 0, NULL, 0}<br>@@ -116,6 +122,14 @@ get_reldate (struct timespec *result= ,<br>=C2=A0 =C2=A0 =C2=A0die (EXIT_FAILURE, 0, _("invalid date format = %s"), quote (flex_date));<br>=C2=A0}<br>=C2=A0<br>+/* Create directory= , called by mkancesdirs(). */<br>+<br>+static int<br>+make_dir(char const *= file, char const * component, void * arg)<br>+{<br>+ =C2=A0return mkdir(co= mponent, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);<br>+}<br>+<br>= =C2=A0/* Update the time of file FILE according to the options given.<br>= =C2=A0 =C2=A0 Return true if successful. =C2=A0*/<br>=C2=A0<br>@@ -130,6 +1= 44,25 @@ touch (char const *file)<br>=C2=A0 =C2=A0 =C2=A0fd =3D STDOUT_FILE= NO;<br>=C2=A0 =C2=A0else if (! (no_create || no_dereference))<br>=C2=A0 =C2= =A0 =C2=A0{<br>+ =C2=A0 =C2=A0 =C2=A0if (! no_create_dirs)<br>+ =C2=A0 =C2= =A0 =C2=A0 =C2=A0{<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0struct savewd wd;= <br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0savewd_init(&wd);<br>+ =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0ptrdiff_t ret =3D mkancesdirs((char*) file, &= ;wd, make_dir, NULL);<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (ret =3D=3D= -1)<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{<br>+ =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0error (0, open_errno, _("cannot mkdir %= s"), quoteaf (file));<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0return false;<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}<br>+ = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0int r =3D savewd_restore(&wd, 0);<br>= + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (r < 0)<br>+ =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0{<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0error (0, open_errno, _("cannot mkdir %s"), quoteaf (file));<b= r>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return false;<br>+ =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0savewd_finish(&wd);<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0}<br>+<br>=C2= =A0 =C2=A0 =C2=A0 =C2=A0/* Try to open FILE, creating it if necessary. =C2= =A0*/<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0fd =3D fd_reopen (STDIN_FILENO, file,<b= r>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0O_WRONLY | O_CREAT | O_NONBLOCK | O_NOCTTY, MODE_RW_UGO);<br>@@ -= 276,7 +309,7 @@ main (int argc, char **argv)<br>=C2=A0 =C2=A0change_times = =3D 0;<br>=C2=A0 =C2=A0no_create =3D use_ref =3D false;<br>=C2=A0<br>- =C2= =A0while ((c =3D getopt_long (argc, argv, "acd:fhmr:t:", longopts= , NULL)) !=3D -1)<br>+ =C2=A0while ((c =3D getopt_long (argc, argv, "a= cd:fhimr:t:", longopts, NULL)) !=3D -1)<br>=C2=A0 =C2=A0 =C2=A0{<br>= =C2=A0 =C2=A0 =C2=A0 =C2=A0switch (c)<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= {<br>@@ -299,6 +332,10 @@ main (int argc, char **argv)<br>=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0no_dereference =3D true;<br>=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0break;<br>=C2=A0<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0case &= #39;i':<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0no_create_dirs =3D true;= <br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break;<br>+<br>=C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0case 'm':<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0change_times |=3D CH_MTIME;<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= break;<br>-- <br>2.20.1<br><br></div> </blockquote></div> --0000000000006458b805e152ef45--
bug-coreutils@HIDDEN
:bug#55937
; Package coreutils
.
Full text available.Received: (at submit) by debbugs.gnu.org; 13 Jun 2022 04:32:20 +0000 From debbugs-submit-bounces <at> debbugs.gnu.org Mon Jun 13 00:32:19 2022 Received: from localhost ([127.0.0.1]:56876 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>) id 1o0bkQ-00042j-V1 for submit <at> debbugs.gnu.org; Mon, 13 Jun 2022 00:32:19 -0400 Received: from lists.gnu.org ([209.51.188.17]:48044) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from <alan.rosenthal@HIDDEN>) id 1o0ZTC-0006kB-1V for submit <at> debbugs.gnu.org; Sun, 12 Jun 2022 22:06:22 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36870) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from <alan.rosenthal@HIDDEN>) id 1o0ZTB-0000ko-TI for bug-coreutils@HIDDEN; Sun, 12 Jun 2022 22:06:21 -0400 Received: from mail-pj1-x1029.google.com ([2607:f8b0:4864:20::1029]:34329) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from <alan.rosenthal@HIDDEN>) id 1o0ZTA-0007Dx-3q for bug-coreutils@HIDDEN; Sun, 12 Jun 2022 22:06:21 -0400 Received: by mail-pj1-x1029.google.com with SMTP id mh16-20020a17090b4ad000b001e8313301f1so7064963pjb.1 for <bug-coreutils@HIDDEN>; Sun, 12 Jun 2022 19:06:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=mime-version:from:date:message-id:subject:to; bh=DMYV6zv4mfrDag0JEKMLjbQRkbw2lGCGE1wCHFeq5dA=; b=c3mKeJCZapIMaIe2ym7faKy1PKI8cr6HAr7CQUu95QtqA8AXTnXcIesMpO7tEIVDeE sbvSP+qIeGVnsJt9ob/lI1XRd614QBSi/P2AIrQXw5R8nSSUyHxaXFyRPI6oXw3J0Xvm xiF7CN/Ltr/c6bzq0nwqPNk45Zu7K04zesrlg9m778kwDQ9/Oyr2J8bGBtDMnFfG1yh2 JE59Pt1yVbEEXoKfQxd6re3vDga7Vq7sAWMze9NkcRjLnNg65Vxth3QDh3jpjzUizQUl Gi/WRIDv4nYbOTgH3GilSxP0mSm77JiU64u9eDUExb1YHvmkAY37Am0VjUsBjSp5D+pr glBw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=DMYV6zv4mfrDag0JEKMLjbQRkbw2lGCGE1wCHFeq5dA=; b=eAAAS4fdZGjtxgnDCfKL06dhy7E2C1PCmvzsNnJ4SpbGocIYW4VotMz77vSNAeaBSt B6H+cdjFk9CBd3fA6SLy5WZj4yxOIFw7MI+g8fW8eJM8ZtiAM4S1sPjLO+BmxDCORWFQ CmY3Ul2FkbgUjd99VEZmjteV0oBXbJTxLCXLSJbl9cfxyh3QOVdlh3JkSVJhP36LLjOJ RAoNqb6VRXiJQGKcOZARmgXLp9bV/rAe7j6iCpx7e1nTZik7S/PXlcicB+EnseIxeaJd if7rdaXBPaaAre/C1sYm9djk+DHaijDdRjV5kL8IRoE3w1swEfNi8vmg9Il6YGzOueKN xfzg== X-Gm-Message-State: AOAM533fbYQxE9uhYmh6SsmEofC5br4J1GYjHoFt+w72KJaRlupDKmdn jCsb32KQ+J7eDJ9bopzs+UHAwPhfaoMm3u3l+WfeOzybGmU= X-Google-Smtp-Source: ABdhPJzUSJ+70APk8jnDnzCIMR9BWDK7ylqyrb1qsWAjW/5/kFTVDnRdChrtc7FLyWe6vMk/tb9D0O+y4wruRbxaG7c= X-Received: by 2002:a17:902:bb90:b0:156:2c05:b34f with SMTP id m16-20020a170902bb9000b001562c05b34fmr57259812pls.53.1655085977530; Sun, 12 Jun 2022 19:06:17 -0700 (PDT) MIME-Version: 1.0 From: Alan Rosenthal <alan.rosenthal@HIDDEN> Date: Sun, 12 Jun 2022 22:05:40 -0400 Message-ID: <CABEWFW8x_Th-O0TdVTNi4fuordVvEZCFPiVqPuUnqQDRrM_OHQ@HIDDEN> Subject: [PATCH] touch: create parent directories if needed To: bug-coreutils@HIDDEN Content-Type: multipart/alternative; boundary="000000000000c3759805e14abb5a" Received-SPF: pass client-ip=2607:f8b0:4864:20::1029; envelope-from=alan.rosenthal@HIDDEN; helo=mail-pj1-x1029.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-Spam-Score: -1.3 (-) X-Debbugs-Envelope-To: submit X-Mailman-Approved-At: Mon, 13 Jun 2022 00:32:18 -0400 X-BeenThere: debbugs-submit <at> debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: <debbugs-submit.debbugs.gnu.org> List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe> List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/> List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org> List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help> List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe> Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org> X-Spam-Score: -2.3 (--) --000000000000c3759805e14abb5a Content-Type: text/plain; charset="UTF-8" `touch a/b/c/d/e` will now be the same as running `mkdir -p a/b/c/d && touch a/b/c/d/e`. Added an option --no-create-dirs to not create any directories. --- src/touch.c | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/touch.c b/src/touch.c index 21c247d0b..9034e8797 100644 --- a/src/touch.c +++ b/src/touch.c @@ -28,10 +28,12 @@ #include "die.h" #include "error.h" #include "fd-reopen.h" +#include "mkancesdirs.h" #include "parse-datetime.h" #include "posixtm.h" #include "posixver.h" #include "quote.h" +#include "savewd.h" #include "stat-time.h" #include "utimens.h" @@ -55,6 +57,9 @@ static int change_times; /* (-c) If true, don't create if not already there. */ static bool no_create; +/* (-c) If true, don't create directories if not already there. */ +static bool no_create_dirs; + /* (-r) If true, use times from a reference file. */ static bool use_ref; @@ -88,6 +93,7 @@ static struct option const longopts[] = {"date", required_argument, NULL, 'd'}, {"reference", required_argument, NULL, 'r'}, {"no-dereference", no_argument, NULL, 'h'}, + {"no_create_dirs", no_argument, NULL, 'i'}, {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, {NULL, 0, NULL, 0} @@ -116,6 +122,14 @@ get_reldate (struct timespec *result, die (EXIT_FAILURE, 0, _("invalid date format %s"), quote (flex_date)); } +/* Create directory, called by mkancesdirs(). */ + +static int +make_dir(char const * file, char const * component, void * arg) +{ + return mkdir(component, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); +} + /* Update the time of file FILE according to the options given. Return true if successful. */ @@ -130,6 +144,25 @@ touch (char const *file) fd = STDOUT_FILENO; else if (! (no_create || no_dereference)) { + if (! no_create_dirs) + { + struct savewd wd; + savewd_init(&wd); + ptrdiff_t ret = mkancesdirs((char*) file, &wd, make_dir, NULL); + if (ret == -1) + { + error (0, open_errno, _("cannot mkdir %s"), quoteaf (file)); + return false; + } + int r = savewd_restore(&wd, 0); + if (r < 0) + { + error (0, open_errno, _("cannot mkdir %s"), quoteaf (file)); + return false; + } + savewd_finish(&wd); + } + /* Try to open FILE, creating it if necessary. */ fd = fd_reopen (STDIN_FILENO, file, O_WRONLY | O_CREAT | O_NONBLOCK | O_NOCTTY, MODE_RW_UGO); @@ -276,7 +309,7 @@ main (int argc, char **argv) change_times = 0; no_create = use_ref = false; - while ((c = getopt_long (argc, argv, "acd:fhmr:t:", longopts, NULL)) != -1) + while ((c = getopt_long (argc, argv, "acd:fhimr:t:", longopts, NULL)) != -1) { switch (c) { @@ -299,6 +332,10 @@ main (int argc, char **argv) no_dereference = true; break; + case 'i': + no_create_dirs = true; + break; + case 'm': change_times |= CH_MTIME; break; -- 2.20.1 --000000000000c3759805e14abb5a Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable <div dir=3D"ltr">`touch a/b/c/d/e` will now be the same as running `mkdir -= p a/b/c/d &&<br>touch a/b/c/d/e`.<br>Added an option --no-create-di= rs to not create any directories.<br>---<br>=C2=A0src/touch.c | 39 ++++++++= ++++++++++++++++++++++++++++++-<br>=C2=A01 file changed, 38 insertions(+), = 1 deletion(-)<br><br>diff --git a/src/touch.c b/src/touch.c<br>index 21c247= d0b..9034e8797 100644<br>--- a/src/touch.c<br>+++ b/src/touch.c<br>@@ -28,1= 0 +28,12 @@<br>=C2=A0#include "die.h"<br>=C2=A0#include "err= or.h"<br>=C2=A0#include "fd-reopen.h"<br>+#include "mka= ncesdirs.h"<br>=C2=A0#include "parse-datetime.h"<br>=C2=A0#i= nclude "posixtm.h"<br>=C2=A0#include "posixver.h"<br>= =C2=A0#include "quote.h"<br>+#include "savewd.h"<br>=C2= =A0#include "stat-time.h"<br>=C2=A0#include "utimens.h"= <br>=C2=A0<br>@@ -55,6 +57,9 @@ static int change_times;<br>=C2=A0/* (-c) I= f true, don't create if not already there. =C2=A0*/<br>=C2=A0static boo= l no_create;<br>=C2=A0<br>+/* (-c) If true, don't create directories if= not already there. =C2=A0*/<br>+static bool no_create_dirs;<br>+<br>=C2=A0= /* (-r) If true, use times from a reference file. =C2=A0*/<br>=C2=A0static = bool use_ref;<br>=C2=A0<br>@@ -88,6 +93,7 @@ static struct option const lon= gopts[] =3D<br>=C2=A0 =C2=A0{"date", required_argument, NULL, = 9;d'},<br>=C2=A0 =C2=A0{"reference", required_argument, NULL,= 'r'},<br>=C2=A0 =C2=A0{"no-dereference", no_argument, NU= LL, 'h'},<br>+ =C2=A0{"no_create_dirs", no_argument, NULL= , 'i'},<br>=C2=A0 =C2=A0{GETOPT_HELP_OPTION_DECL},<br>=C2=A0 =C2=A0= {GETOPT_VERSION_OPTION_DECL},<br>=C2=A0 =C2=A0{NULL, 0, NULL, 0}<br>@@ -116= ,6 +122,14 @@ get_reldate (struct timespec *result,<br>=C2=A0 =C2=A0 =C2=A0= die (EXIT_FAILURE, 0, _("invalid date format %s"), quote (flex_da= te));<br>=C2=A0}<br>=C2=A0<br>+/* Create directory, called by mkancesdirs()= . */<br>+<br>+static int<br>+make_dir(char const * file, char const * compo= nent, void * arg)<br>+{<br>+ =C2=A0return mkdir(component, S_IRWXU | S_IRGR= P | S_IXGRP | S_IROTH | S_IXOTH);<br>+}<br>+<br>=C2=A0/* Update the time of= file FILE according to the options given.<br>=C2=A0 =C2=A0 Return true if = successful. =C2=A0*/<br>=C2=A0<br>@@ -130,6 +144,25 @@ touch (char const *f= ile)<br>=C2=A0 =C2=A0 =C2=A0fd =3D STDOUT_FILENO;<br>=C2=A0 =C2=A0else if (= ! (no_create || no_dereference))<br>=C2=A0 =C2=A0 =C2=A0{<br>+ =C2=A0 =C2= =A0 =C2=A0if (! no_create_dirs)<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0{<br>+ =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0struct savewd wd;<br>+ =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0savewd_init(&wd);<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0p= trdiff_t ret =3D mkancesdirs((char*) file, &wd, make_dir, NULL);<br>+ = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (ret =3D=3D -1)<br>+ =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0{<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0error (0, open_errno, _("cannot mkdir %s"), quoteaf (file))= ;<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return false;<br>+ = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0int r =3D savewd_restore(&wd, 0);<br>+ =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0if (r < 0)<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{<br>= + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0error (0, open_errno, _(&= quot;cannot mkdir %s"), quoteaf (file));<br>+ =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0return false;<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0}<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0savewd_finish(&wd);<= br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0}<br>+<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0/* Try= to open FILE, creating it if necessary. =C2=A0*/<br>=C2=A0 =C2=A0 =C2=A0 = =C2=A0fd =3D fd_reopen (STDIN_FILENO, file,<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0O_WRONLY | O_CREAT |= O_NONBLOCK | O_NOCTTY, MODE_RW_UGO);<br>@@ -276,7 +309,7 @@ main (int argc= , char **argv)<br>=C2=A0 =C2=A0change_times =3D 0;<br>=C2=A0 =C2=A0no_creat= e =3D use_ref =3D false;<br>=C2=A0<br>- =C2=A0while ((c =3D getopt_long (ar= gc, argv, "acd:fhmr:t:", longopts, NULL)) !=3D -1)<br>+ =C2=A0whi= le ((c =3D getopt_long (argc, argv, "acd:fhimr:t:", longopts, NUL= L)) !=3D -1)<br>=C2=A0 =C2=A0 =C2=A0{<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0switch = (c)<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{<br>@@ -299,6 +332,10 @@ main (in= t argc, char **argv)<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0no_derefer= ence =3D true;<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break;<br>=C2=A0= <br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0case 'i':<br>+ =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0no_create_dirs =3D true;<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0break;<br>+<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case 'm':<br= >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0change_times |=3D CH_MTIME;<br>= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break;<br>-- <br>2.20.1<br><br></d= iv> --000000000000c3759805e14abb5a--
Alan Rosenthal <alan.rosenthal@HIDDEN>
:bug-coreutils@HIDDEN
.
Full text available.bug-coreutils@HIDDEN
:bug#55937
; Package coreutils
.
Full text available.
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997 nCipher Corporation Ltd,
1994-97 Ian Jackson.