From owner-freebsd-hackers@FreeBSD.ORG Tue Oct 10 15:26:14 2006 Return-Path: X-Original-To: freebsd-hackers@freebsd.org Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 1B2F016A49E for ; Tue, 10 Oct 2006 15:26:14 +0000 (UTC) (envelope-from ru@rambler-co.ru) Received: from relay0.rambler.ru (relay0.rambler.ru [81.19.66.187]) by mx1.FreeBSD.org (Postfix) with ESMTP id 7066643DA7 for ; Tue, 10 Oct 2006 15:24:39 +0000 (GMT) (envelope-from ru@rambler-co.ru) Received: from relay0.rambler.ru (localhost [127.0.0.1]) by relay0.rambler.ru (Postfix) with ESMTP id 927055DE1; Tue, 10 Oct 2006 19:24:31 +0400 (MSD) Received: from edoofus.park.rambler.ru (unknown [81.19.65.108]) by relay0.rambler.ru (Postfix) with ESMTP id 6F0DF5D9A; Tue, 10 Oct 2006 19:24:31 +0400 (MSD) Received: (from ru@localhost) by edoofus.park.rambler.ru (8.13.8/8.13.8) id k9AFOXfb035954; Tue, 10 Oct 2006 19:24:33 +0400 (MSD) (envelope-from ru) Date: Tue, 10 Oct 2006 19:24:33 +0400 From: Ruslan Ermilov To: Alex Unleashed Message-ID: <20061010152433.GA35377@rambler-co.ru> References: <5e4707340610100624j38ce9f8du7741bd027eb8cb1b@mail.gmail.com> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="DocE+STaALJfprDB" Content-Disposition: inline In-Reply-To: <5e4707340610100624j38ce9f8du7741bd027eb8cb1b@mail.gmail.com> User-Agent: Mutt/1.5.13 (2006-08-11) X-Virus-Scanned: No virus found Cc: freebsd-hackers@freebsd.org Subject: Re: mkdir -m option POSIX compliance X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 10 Oct 2006 15:26:14 -0000 --DocE+STaALJfprDB Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Tue, Oct 10, 2006 at 03:24:14PM +0200, Alex Unleashed wrote: > Hi all, >=20 > "mkdir -m mode -p /some/directory" calls chmod() on /some/directory even = if > it already exists, effectively changing the mode. POSIX specifies that th= is > mode may only be applied to newly created directories. Patch attached. > Please look at the URLs referenced in the patch for further information. >=20 I've modified your patch slightly, to save a variable. How does this look to you? %%% Index: mkdir.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /home/ncvs/src/bin/mkdir/mkdir.c,v retrieving revision 1.32 diff -u -p -r1.32 mkdir.c --- mkdir.c 9 Feb 2005 17:37:38 -0000 1.32 +++ mkdir.c 10 Oct 2006 15:22:05 -0000 @@ -99,19 +99,19 @@ main(int argc, char *argv[]) } =20 for (exitval =3D 0; *argv !=3D NULL; ++argv) { - success =3D 1; if (pflag) { - if (build(*argv, omode)) - success =3D 0; + success =3D build(*argv, omode); } else if (mkdir(*argv, omode) < 0) { if (errno =3D=3D ENOTDIR || errno =3D=3D ENOENT) warn("%s", dirname(*argv)); else warn("%s", *argv); success =3D 0; - } else if (vflag) - (void)printf("%s\n", *argv); - =09 + } else { + success =3D 1; + if (vflag) + (void)printf("%s\n", *argv); + } if (!success) exitval =3D 1; /* @@ -119,9 +119,10 @@ main(int argc, char *argv[]) * nine bits, so if you try to set a mode including the * sticky, setuid, setgid bits you lose them. Don't do * this unless the user has specifically requested a mode, - * as chmod will (obviously) ignore the umask. + * as chmod will (obviously) ignore the umask. Do this + * on newly created directories only. */ - if (success && mode !=3D NULL && chmod(*argv, omode) =3D=3D -1) { + if (success =3D=3D 1 && mode !=3D NULL && chmod(*argv, omode) =3D=3D -1)= { warn("%s", *argv); exitval =3D 1; } @@ -129,6 +130,11 @@ main(int argc, char *argv[]) exit(exitval); } =20 + +/* + * Returns 1 if a directory has been created, + * 2 if it already existed, and 0 on failure. + */ int build(char *path, mode_t omode) { @@ -139,7 +145,7 @@ build(char *path, mode_t omode) =20 p =3D path; oumask =3D 0; - retval =3D 0; + retval =3D 1; if (p[0] =3D=3D '/') /* Skip leading '/'. */ ++p; for (first =3D 1, last =3D 0; !last ; ++p) { @@ -174,7 +180,7 @@ build(char *path, mode_t omode) if (errno =3D=3D EEXIST || errno =3D=3D EISDIR) { if (stat(path, &sb) < 0) { warn("%s", path); - retval =3D 1; + retval =3D 0; break; } else if (!S_ISDIR(sb.st_mode)) { if (last) @@ -182,12 +188,14 @@ build(char *path, mode_t omode) else errno =3D ENOTDIR; warn("%s", path); - retval =3D 1; + retval =3D 0; break; } + if (last) + retval =3D 2; } else { warn("%s", path); - retval =3D 1; + retval =3D 0; break; } } else if (vflag) %%% Cheers, --=20 Ruslan Ermilov ru@FreeBSD.org FreeBSD committer --DocE+STaALJfprDB Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.5 (FreeBSD) iD8DBQFFK7sxqRfpzJluFF4RAjBRAJ4vjE51N5GklJjcAu+yU1hXhwjvsgCgkBgQ FKCY6JqSBsdZ7SznScOAlGY= =QIFY -----END PGP SIGNATURE----- --DocE+STaALJfprDB--