Re: mkdir -p and network drives

2005-05-04 Thread Eric Blake
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

According to Pierre A. Humblet on 5/2/2005 9:22 PM:
 According to the Cygwin Faq,
 
 *
 Why doesn't `mkdir -p' work on a network share?
 Unfortunately, you cannot do something like this: 
 
 bash$ mkdir -p //MACHINE/Share/path/to/new/dir
 mkdir: cannot create directory `//MACHINE': No such file or directory
 
 This is because mkdir checks for the existence of each directory on the path,
 creating them as necessary. Since `//MACHINE' is not a directory (you can't cd
 to it either), mkdir tries to create it, and fails. 
 **
 
 This behavior would be fine with me, but the latest mkdir (GNU coreutils)
 5.3.0
 creates /MACHINE/Share/path/to/new/dir and returns 0
 
 Pierre
 

It appears you have uncovered an upstream bug - in line 210 of CVS
coreutils/lib/makepath.c (unchanged from 5.3.0), `mkdir -p' is attempting
an optimization by blindly changing directory to / if the first character
is '/', without regards to whether there is a leading // such that
changing to / violates POSIX naming semantics.  In my opinion, it should
be possible to rewrite the algorithm to make even your test case works,
eliminating the cygwin FAQ entry:  rather than starting at the left and
making sure each path component exists, the algorithm could start at the
right and successively prune each rightmost component until it no longer
gets ENOENT (or gets to the empty string), then build back up from that
point.  Then, even though //MACHINE does not resolve to a directory,
`mkdir -p //MACHINE/Share/existing/nonexisting' only has to check whether
//MACHINE/Share/existing exists, and create nonexisting from there, rather
than starting all the way from the problematic /, //, or //MACHINE.  The
only drawback to this approach is that it would then require up to n
stat() calls to decide where to start making directories, each processing
O(n) names, which is the exact O(n^2) syscall overhead that the code was
optimized to try to avoid by starting blindly at the leftmost component.
The only other approach I can think of is to special case leading // (at
least on cygwin, leading // should start after //MACHINE/Share/), but not
all POSIX-compliant hosts have the same semantics for leading //, so I
don't know how well such a special case would fold into upstream coreutils.

- --
Life is short - so eat dessert first!

Eric Blake [EMAIL PROTECTED]
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.0 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD4DBQFCd3cZ84KuGfSFAYARAqf8AJ4waeVK7NWOh0D4fz84LD5jcBmPpQCY9blL
6lOcqZkvuNWndvgAjElQ9A==
=sDhN
-END PGP SIGNATURE-


___
Bug-coreutils mailing list
Bug-coreutils@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-coreutils


chmod -w file now complains if file is still writable afterwards

2005-05-04 Thread Paul Eggert
For quite some time I've been annoyed that chmod -w file can leave
the file writeable afterwards, if your umask is restrictive.  You're
supposed to use chmod a-w file if you really want the file to be
unwriteable.

This is a common trap for novices to fall into, and I think it'd be
better if chmod diagnosed the mistake, in addition to performing the
requested action.  I just checked POSIX, and it allows chmod to
diagnose errors like chmod -w file so I installed the following
patch.

Another option would be for chmod -w file to silently adjust itself
to behave like chmod a-w file; POSIX allows that too.  If you think
that's better I could install a patch along those lines instead.

2005-05-04  Paul Eggert  [EMAIL PROTECTED]

* NEWS: chmod -w now complains if it differs from chmod a-w.
* src/chmod.c: Include quotearg.h.
(diagnose_surprises): New var.
(process_file): Diagnose surprises.  Simplify the logic a bit,
while we're at it.
(main): Prepare to diagnose surprises.  Remove useless code for
'-' option.
* tests/chmod/Makefile.am (TESTS): Add umask-x.
* tests/chmod/umask-x: New file.

Index: NEWS
===
RCS file: /fetish/cu/NEWS,v
retrieving revision 1.284
diff -p -u -r1.284 NEWS
--- NEWS2 May 2005 18:40:20 -   1.284
+++ NEWS4 May 2005 17:18:47 -
@@ -124,6 +124,9 @@ GNU coreutils NEWS  
 
 ** New features
 
+  chmod -w now complains if its behavior differs from what chmod a-w
+  would do, and similarly for chmod -r, chmod -x, etc.
+
   join now supports a NUL field separator, e.g., join -t '\0'.
   join now detects and reports incompatible options, e.g., join -t x -t y,
 
Index: doc/coreutils.texi
===
RCS file: /fetish/cu/doc/coreutils.texi,v
retrieving revision 1.254
diff -p -u -r1.254 coreutils.texi
--- doc/coreutils.texi  2 May 2005 18:41:12 -   1.254
+++ doc/coreutils.texi  4 May 2005 17:18:48 -
@@ -8451,9 +8451,11 @@ recursive directory traversals.
 
 If used, @var{mode} specifies the new permissions.
 For details, see the section on @ref{File permissions}.
-In the extremely rare cases where @var{mode} has leading @samp{-}, a
-portable script should use @option{--} first, e.g., @samp{chmod -- -w
-file}.  Typically, though, @samp{chmod a-w file} is preferable.
+If you really want @var{mode} to have a leading @samp{-}, you should
+use @option{--} first, e.g., @samp{chmod -- -w file}.  Typically,
+though, @samp{chmod a-w file} is preferable, and @command{chmod -w
+file} (without the @option{--}) complains if it behaves differently
+from what @samp{chmod a-w file} would do.
 
 The program accepts the following options.  Also see @ref{Common options}.
 
Index: src/chmod.c
===
RCS file: /fetish/cu/src/chmod.c,v
retrieving revision 1.109
diff -p -u -r1.109 chmod.c
--- src/chmod.c 28 Apr 2005 16:29:59 -  1.109
+++ src/chmod.c 4 May 2005 17:18:48 -
@@ -29,6 +29,7 @@
 #include filemode.h
 #include modechange.h
 #include quote.h
+#include quotearg.h
 #include root-dev-ino.h
 #include xfts.h
 
@@ -72,6 +73,11 @@ static bool recurse;
 /* If true, force silence (no error messages). */
 static bool force_silent;
 
+/* If true, diagnose surprises from naive misuses like chmod -r file.
+   POSIX allows diagnostics here, as portable code is supposed to use
+   chmod -- -r file.  */
+static bool diagnose_surprises;
+
 /* Level of verbosity.  */
 static enum Verbosity verbosity = V_off;
 
@@ -176,10 +182,10 @@ process_file (FTS *fts, FTSENT *ent)
   char const *file_full_name = ent-fts_path;
   char const *file = ent-fts_accpath;
   const struct stat *file_stats = ent-fts_statp;
+  mode_t old_mode IF_LINT (= 0);
   mode_t new_mode IF_LINT (= 0);
   bool ok = true;
-  bool do_chmod;
-  bool symlink_changed = true;
+  bool chmod_succeeded = false;
 
   switch (ent-fts_info)
 {
@@ -206,48 +212,65 @@ process_file (FTS *fts, FTSENT *ent)
   break;
 }
 
-  do_chmod = ok;
-
-  if (do_chmod  ROOT_DEV_INO_CHECK (root_dev_ino, file_stats))
+  if (ok  ROOT_DEV_INO_CHECK (root_dev_ino, file_stats))
 {
   ROOT_DEV_INO_WARN (file_full_name);
   ok = false;
-  do_chmod = false;
 }
 
-  if (do_chmod)
+  if (ok)
 {
-  new_mode = mode_adjust (file_stats-st_mode, change, umask_value);
+  old_mode = file_stats-st_mode;
+  new_mode = mode_adjust (old_mode, change, umask_value);
 
-  if (S_ISLNK (file_stats-st_mode))
-   symlink_changed = false;
-  else
+  if (! S_ISLNK (old_mode))
{
- ok = (chmod (file, new_mode) == 0);
-
- if (! (ok | force_silent))
-   error (0, errno, _(changing permissions of %s),
-  quote (file_full_name));
+ if (chmod (file, new_mode) == 0)
+   chmod_succeeded = 

Re: chmod -w file now complains if file is still writable afterwards

2005-05-04 Thread Eric Blake
 This is a common trap for novices to fall into, and I think it'd be
 better if chmod diagnosed the mistake, in addition to performing the
 requested action.  I just checked POSIX, and it allows chmod to
 diagnose errors like chmod -w file so I installed the following
 patch.

It took me a while to follow your logic of how POSIX allows this, so I'm
stating why I am in agreement.  The only option chmod is required to
support is -R, so we can define our own semantics for extension options
such as -w, -r, etc., where our extension options happen to look like valid
mode strings.  There is definitely a parsing difference between
`chmod -- any-mode file' or `chmod non-dash-mode file' with 0 options
and 2 arguments, and `chmod -dash-mode file' with 1 option
and 1 argument, and POSIX only dictates the behavior of the first.

Other questions, though - with our extension options, should we interpret
`chmod -w a+x foo' the same as `chmod -- -w ./a+x ./foo' or like
`chmod -- -w,a+x ./foo'?  Put in other words, if the first of multiple
non-option arguments matches a mode, should it be treated as a mode
or a file when extension options are present.  Also, POSIX allows modes
that look like long options - can the code be made to treat `chmod --w foo'
the same as it would `chmod -w foo' by seeing if unrecognized long options
match a valid mode string?

 
 Another option would be for chmod -w file to silently adjust itself
 to behave like chmod a-w file; POSIX allows that too.  If you think
 that's better I could install a patch along those lines instead.
 

I tend to favor your existing patch as the correct approach.  I would find
it confusing if the extension syntax `chmod -w file' behaved differently
than the compliant syntax `chmod -- -w file' on which permissions it
affected, unless we documented the -w extension better.

Speaking of which, the `chmod --help' wording could be improved (perhaps
with examples); it does not mention -w, -r, etc. as being extension options,
and wrongly states that one or more of the letters ugoa is required as who,
and one or more of the letters rwxXstugo is required as perm/permcopy.

--
Eric Blake




___
Bug-coreutils mailing list
Bug-coreutils@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-coreutils


Re: chmod -w file now complains if file is still writable afterwards

2005-05-04 Thread Paul Eggert
[EMAIL PROTECTED] (Eric Blake) writes:

 Other questions, though - with our extension options, should we interpret
 `chmod -w a+x foo' the same as `chmod -- -w ./a+x ./foo' or like
 `chmod -- -w,a+x ./foo'?

It's been the former for a while; I guess that's OK.

 POSIX allows modes that look like long options - can the code be
 made to treat `chmod --w foo' the same as it would `chmod -w foo' by
 seeing if unrecognized long options match a valid mode string?

Not in general, because plain -- is a valid mode option, but POSIX
specifies a different meaning for --.  I don't think it's worth
worrying much about other leading--- forms, as nobody is likely to
use them (unlike -w, say).

 Speaking of which, the `chmod --help' wording could be improved (perhaps
 with examples); it does not mention -w, -r, etc. as being extension options,

I doubt whether this level of detail needs to be in the usage; usage
is just meant to be a brief reminder, not a formal spec.

 and wrongly states that one or more of the letters ugoa is required as who,
 and one or more of the letters rwxXstugo is required as perm/permcopy.

Good point.  That's fixed in CVS.  It now says:

Each MODE is of the form `[ugoa]*([-+=]([rwxXst]*|[ugo]))+'.


___
Bug-coreutils mailing list
Bug-coreutils@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-coreutils