bin/127932: mkdir -p PATH fails if a directory in PATH is on a
read-only fs
Jaakko Heinonen
jh at saunalahti.fi
Fri Oct 31 10:10:05 PDT 2008
The following reply was made to PR bin/127932; it has been noted by GNATS.
From: Jaakko Heinonen <jh at saunalahti.fi>
To: Till Toenges <tt at kyon.de>
Cc: bug-followup at freebsd.org
Subject: Re: bin/127932: mkdir -p PATH fails if a directory in PATH is on a
read-only fs
Date: Fri, 31 Oct 2008 19:01:13 +0200
Hi,
On 2008-10-08, Till Toenges wrote:
> Treat EROFS like EISDIR and EEXIST.
>
> Patch attached with submission follows:
>
> --- /usr/src/bin/mkdir/mkdir.c 2006-10-10 22:18:20.000000000 +0200
> +++ /root/mkdir/mkdir.c 2008-10-08 01:44:22.000000000 +0200
> @@ -177,7 +177,7 @@
> if (last)
> (void)umask(oumask);
> if (mkdir(path, last ? omode : S_IRWXU | S_IRWXG | S_IRWXO) < 0) {
> - if (errno == EEXIST || errno == EISDIR) {
> + if (errno == EEXIST || errno == EISDIR || errno == EROFS) {
> if (stat(path, &sb) < 0) {
> warn("%s", path);
> retval = 0;
This has patch has a problem. Patched mkdir(1) gives a bogus error
message if a directory creation fails on read-only file system.
$ mkdir -p foo (unpatched)
mkdir: foo: Read-only file system
$ mkdir -p foo (patched)
mkdir: foo: No such file or directory
The latter error message is very misleading because the real reason for
the failure is read-only file system.
Maybe save the original error number and if stat(2) fails in EROFS case
then use it instead of the error from stat(2). Something like this:
%%%
Index: bin/mkdir/mkdir.c
===================================================================
--- bin/mkdir/mkdir.c (revision 183921)
+++ bin/mkdir/mkdir.c (working copy)
@@ -140,7 +140,7 @@ build(char *path, mode_t omode)
{
struct stat sb;
mode_t numask, oumask;
- int first, last, retval;
+ int first, last, retval, serrno;
char *p;
p = path;
@@ -177,8 +177,12 @@ build(char *path, mode_t omode)
if (last)
(void)umask(oumask);
if (mkdir(path, last ? omode : S_IRWXU | S_IRWXG | S_IRWXO) < 0) {
- if (errno == EEXIST || errno == EISDIR) {
+ if (errno == EEXIST || errno == EISDIR ||
+ errno == EROFS) {
+ serrno = errno;
if (stat(path, &sb) < 0) {
+ if (serrno == EROFS)
+ errno = EROFS;
warn("%s", path);
retval = 0;
break;
%%%
--
Jaakko
More information about the freebsd-bugs
mailing list