Date: Tue, 10 Oct 2006 19:24:33 +0400 From: Ruslan Ermilov <ru@freebsd.org> To: Alex Unleashed <unledev@gmail.com> Cc: freebsd-hackers@freebsd.org Subject: Re: mkdir -m option POSIX compliance Message-ID: <20061010152433.GA35377@rambler-co.ru> In-Reply-To: <5e4707340610100624j38ce9f8du7741bd027eb8cb1b@mail.gmail.com> References: <5e4707340610100624j38ce9f8du7741bd027eb8cb1b@mail.gmail.com>
next in thread | previous in thread | raw e-mail | index | archive | help
--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--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20061010152433.GA35377>