[816] in NetBSD-Development

home help back first fref pref prev next nref lref last post

mkdir -p doesn't ignore existing directories

daemon@ATHENA.MIT.EDU (Greg Hudson)
Sun Jun 25 16:55:31 1995

Date: Sun, 25 Jun 1995 16:54:35 -0400
From: Greg Hudson <ghudson@MIT.EDU>
To: gnats-bugs@NetBSD.ORG
Cc: netbsd-dev@MIT.EDU
Reply-To: ghudson@MIT.EDU


>Submitter-Id:	net
>Originator:	Greg Hudson
>Organization:
	MIT SIPB
>Confidential:	no
>Synopsis:	mkdir -p doesn't ignore existing directories
>Severity:	serious
>Priority:	low
>Category:	bin
>Class:		sw-bug
>Release:	June 25, 1995
>Environment:
	
System: NetBSD glacier 1.0A NetBSD 1.0A (GLACIER) #1: Fri May 5 10:55:51 EDT 1995 ghudson@glacier:/afs/sipb.mit.edu/project/netbsd/dev/current-source/src/sys/arch/i386/compile/GLACIER i386


>Description:
	According to POSIX 1003.2-1992 (as amended by 1003.2a-1992, I
	guess), section 4.41.3, mkdir -p is supposed to ignore arguments
	which name existing directories:

		"Each dir operand that names an existing directory shall
		be ignored without error."

	NetBSD's mkdir -p gives an error message if you give "mkdir -p"
	an existing directory argument.
>How-To-Repeat:
	mkdir -p /tmp
>Fix:
	Here is a sample fix which applies the same logic to the last path
	component as it does to the internal path components.  It might be
	possible to simplify the logic of the loop somewhat.

*** 1.1	1995/06/25 20:16:44
--- mkdir.c	1995/06/25 20:30:20
***************
*** 133,145 ****
  {
  	struct stat sb;
  	register char *slash;
  
! 	/* skip leading slashes */
! 	slash = path;
! 	while (*slash == '/')
! 		slash++;
  
! 	while ((slash = strchr(slash, '/')) != NULL) {
  		*slash = '\0';
  
  		if (stat(path, &sb)) {
--- 133,146 ----
  {
  	struct stat sb;
  	register char *slash;
+ 	int done = 0;
  
! 	/* Find first slash after leading slash. */
! 	slash = path + strspn(path, "/");
! 	slash += strcspn(slash, "/");
  
! 	while (!done) {
! 		done = (*slash == '\0');
  		*slash = '\0';
  
  		if (stat(path, &sb)) {
***************
*** 152,166 ****
  			return 1;
  		}
  		    
! 		/* skip multiple slashes */
! 		*slash++ = '/';
! 		while (*slash == '/')
! 			slash++;
! 	}
! 
! 	if (mkdir (path, mode)) {
! 		warn("%s", path);
! 		return 1;
  	}
  
  	return(0);
--- 153,164 ----
  			return 1;
  		}
  		    
! 		/* skip multiple slashes, and find next slash (or the end) */
! 		if (!done) {
! 			*slash++ = '/';
! 			slash += strspn(slash, "/");
! 			slash += strcspn(slash, "/");
! 		}
  	}
  
  	return(0);

home help back first fref pref prev next nref lref last post