mkdir: Fix created directory permissions
Previously, with -p, the specified directory and all of its parents would be 0777&~filemask (regardless of the -m flag). POSIX says parent directories must created as (0300|~filemask)&0777, and of course if -m is set, the specified directory should be created with those permissions. Additionally, POSIX says that for symbolic_mode strings, + and - should be interpretted relative to a default mode of 0777 (not 0). Without -p, previously the directory would be created first with 0777&~filemask (before a chmod), but POSIX says that the directory shall at no point in time have permissions less restrictive than the -m mode argument. Rather than dealing with mkdir removing the filemask bits by calling chmod afterward, just clear the umask and remove the bits manually.
This commit is contained in:
		
				
					committed by
					
						 Anselm R Garbe
						Anselm R Garbe
					
				
			
			
				
	
			
			
			
						parent
						
							6ac5f01cc9
						
					
				
				
					commit
					529e50a7ad
				
			| @@ -7,7 +7,7 @@ | ||||
| #include "../util.h" | ||||
|  | ||||
| int | ||||
| mkdirp(const char *path) | ||||
| mkdirp(const char *path, mode_t mode, mode_t pmode) | ||||
| { | ||||
| 	char tmp[PATH_MAX], *p; | ||||
| 	struct stat st; | ||||
| @@ -25,13 +25,13 @@ mkdirp(const char *path) | ||||
| 		if (*p != '/') | ||||
| 			continue; | ||||
| 		*p = '\0'; | ||||
| 		if (mkdir(tmp, S_IRWXU | S_IRWXG | S_IRWXO) < 0 && errno != EEXIST) { | ||||
| 		if (mkdir(tmp, pmode) < 0 && errno != EEXIST) { | ||||
| 			weprintf("mkdir %s:", tmp); | ||||
| 			return -1; | ||||
| 		} | ||||
| 		*p = '/'; | ||||
| 	} | ||||
| 	if (mkdir(tmp, S_IRWXU | S_IRWXG | S_IRWXO) < 0 && errno != EEXIST) { | ||||
| 	if (mkdir(tmp, mode) < 0 && errno != EEXIST) { | ||||
| 		weprintf("mkdir %s:", tmp); | ||||
| 		return -1; | ||||
| 	} | ||||
|   | ||||
							
								
								
									
										19
									
								
								mkdir.c
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								mkdir.c
									
									
									
									
									
								
							| @@ -15,17 +15,18 @@ usage(void) | ||||
| int | ||||
| main(int argc, char *argv[]) | ||||
| { | ||||
| 	mode_t mode = 0, mask; | ||||
| 	int pflag = 0, mflag = 0, ret = 0; | ||||
| 	mode_t mode, mask; | ||||
| 	int pflag = 0, ret = 0; | ||||
|  | ||||
| 	mask = umask(0); | ||||
| 	mode = 0777 & ~mask; | ||||
|  | ||||
| 	ARGBEGIN { | ||||
| 	case 'p': | ||||
| 		pflag = 1; | ||||
| 		break; | ||||
| 	case 'm': | ||||
| 		mflag = 1; | ||||
| 		mask = getumask(); | ||||
| 		mode = parsemode(EARGF(usage()), mode, mask); | ||||
| 		mode = parsemode(EARGF(usage()), 0777, mask); | ||||
| 		break; | ||||
| 	default: | ||||
| 		usage(); | ||||
| @@ -36,16 +37,12 @@ main(int argc, char *argv[]) | ||||
|  | ||||
| 	for (; *argv; argc--, argv++) { | ||||
| 		if (pflag) { | ||||
| 			if (mkdirp(*argv) < 0) | ||||
| 			if (mkdirp(*argv, mode, 0777 & (~mask | 0300)) < 0) | ||||
| 				ret = 1; | ||||
| 		} else if (mkdir(*argv, S_IRWXU | S_IRWXG | S_IRWXO) < 0) { | ||||
| 		} else if (mkdir(*argv, mode) < 0) { | ||||
| 			weprintf("mkdir %s:", *argv); | ||||
| 			ret = 1; | ||||
| 		} | ||||
| 		if (mflag && chmod(*argv, mode) < 0) { | ||||
| 			weprintf("chmod %s:", *argv); | ||||
| 			ret = 1; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return ret; | ||||
|   | ||||
							
								
								
									
										2
									
								
								tar.c
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								tar.c
									
									
									
									
									
								
							| @@ -262,7 +262,7 @@ unarchive(char *fname, ssize_t l, char b[BLKSIZ]) | ||||
| 		weprintf("remove %s:", fname); | ||||
|  | ||||
| 	tmp = estrdup(fname); | ||||
| 	mkdirp(dirname(tmp)); | ||||
| 	mkdirp(dirname(tmp), 0777, 0777); | ||||
| 	free(tmp); | ||||
|  | ||||
| 	switch (h->type) { | ||||
|   | ||||
							
								
								
									
										2
									
								
								util.h
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								util.h
									
									
									
									
									
								
							| @@ -75,6 +75,6 @@ long long strtonum(const char *, long long, long long, const char **); | ||||
| long long enstrtonum(int, const char *, long long, long long); | ||||
| long long estrtonum(const char *, long long, long long); | ||||
| size_t unescape(char *); | ||||
| int mkdirp(const char *); | ||||
| int mkdirp(const char *, mode_t, mode_t); | ||||
| #undef memmem | ||||
| void *memmem(const void *, size_t, const void *, size_t); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user