mkdir -p
Version:
coreutils-5.92 (fixed in 5.93)
How it is diagnosed (reproduced or source analysis)?
Reproduced
How to reproduce?
use command
$ coreutils-5.92/src/mkdir -p nonexistent/.
--- where nonexistent is a non-existing dir name. Note the “/.” is required for this failure.
Symptom:
Early termination (rejecting valid input).
In the wrong version, ./src/mkdir -p nonexistent/. failed to create the directory nonexistent/. , and reported the error message: mkdir: cannot create directory `nonexistent/.': File exists
The correct behavior should be for mkdir to create this dir.
Root cause:
Comments written by us is in blue color.
/* This function is to create the dir hierarchy one subdir after another.
In the buggy execution, arg = “nonexistent/.” */
bool make_dir_parents (char const *arg, ...)
{
.. .. ..
if (retval)
{
/* Once we reached here, the “nonexistent” is already created.
At this point mkdir is supposed to go on to create the next
level subdir, in the failure case it is “.”. Therefore, the
buggy code will call ‘mkdir’ system call on “.”, which will
fail because the dir it represents: “nonexistent”, already
exists! The patch is to not terminate the execution and
print the error message so soon, but further checks if
this is a “.” or “..”... */
+ bool dir_known_to_exist = (mkdir (basename_dir, mode) == 0);
+ int mkdir_errno = errno;
+ struct stat sbuf;
+ if ( ! dir_known_to_exist)
+ dir_known_to_exist = (stat (basename_dir, &sbuf) == 0
+ && S_ISDIR (sbuf.st_mode));
- if (mkdir (basename_dir, mode) != 0)
+ if ( ! dir_known_to_exist)
{
/* The original message was printed here, when mkdir system call
failed */
- error (0, errno, _("cannot create directory %s"), quote (dir));
+ error (0, mkdir_errno,
+ _("cannot create directory %s"), quote (dir));
retval = false;
}
.. .. ..
}
}
Is there an error message?
Yes. In this case, the error message is very useful to diagnose the failure.
Can Errlog automatically insert the error msg?
Yes. The error pattern is system call error return, therefore Errlog can print the error of mkdir.