libposix: drafted chdir, fchdir and mkdir
This commit is contained in:
		| @@ -89,6 +89,9 @@ typedef unsigned long clock_t; | |||||||
| extern void POSIX_exit(int code) __attribute__((noreturn)); | extern void POSIX_exit(int code) __attribute__((noreturn)); | ||||||
| extern int POSIX_chmod(int *errnop, const char *path, int mode); | extern int POSIX_chmod(int *errnop, const char *path, int mode); | ||||||
| extern int POSIX_fchmodat(int *errnop, int fd, const char *path, long mode, int flag); | extern int POSIX_fchmodat(int *errnop, int fd, const char *path, long mode, int flag); | ||||||
|  | extern int POSIX_chdir(int *errnop, const char *path); | ||||||
|  | extern int POSIX_fchdir(int *errnop, int fd); | ||||||
|  | extern int POSIX_mkdir(int *errnop, const char *path, int mode); | ||||||
| extern int POSIX_close(int *errnop, int file); | extern int POSIX_close(int *errnop, int file); | ||||||
| extern int POSIX_execve(int *errnop, const char *name, char * const*argv, char * const*env); | extern int POSIX_execve(int *errnop, const char *name, char * const*argv, char * const*env); | ||||||
| extern int POSIX_fork(int *errnop); | extern int POSIX_fork(int *errnop); | ||||||
|   | |||||||
| @@ -475,6 +475,104 @@ FailWithError: | |||||||
| 	return -1; | 	return -1; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | int | ||||||
|  | POSIX_chdir(int *errnop, const char *path) | ||||||
|  | { | ||||||
|  | 	Dir *d = nil; | ||||||
|  | 	PosixError e = 0; | ||||||
|  |  | ||||||
|  | 	if(path == nil){ | ||||||
|  | 		e = PosixEFAULT; | ||||||
|  | 	} else { | ||||||
|  | 		d = dirstat(path); | ||||||
|  | 		if(d == nil){ | ||||||
|  | 			e = PosixENOENT; | ||||||
|  | 		} else { | ||||||
|  | 			if((d->mode & DMDIR) == 0) | ||||||
|  | 				e = PosixENOTDIR; | ||||||
|  | 			free(d); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	if(e != 0) | ||||||
|  | 		goto FailWithError; | ||||||
|  |  | ||||||
|  | 	if(chdir(path) == 0) | ||||||
|  | 		return 0; | ||||||
|  |  | ||||||
|  | 	*errnop = __libposix_translate_errstr((uintptr_t)POSIX_chdir); | ||||||
|  | 	return -1; | ||||||
|  |  | ||||||
|  | FailWithError: | ||||||
|  | 	*errnop = __libposix_get_errno(e); | ||||||
|  | 	return -1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int | ||||||
|  | POSIX_fchdir(int *errnop, int fd) | ||||||
|  | { | ||||||
|  | 	Dir *d; | ||||||
|  | 	PosixError e = 0; | ||||||
|  | 	char buf[4096]; | ||||||
|  |  | ||||||
|  | 	if(fd < 0){ | ||||||
|  | 		e = PosixEBADF; | ||||||
|  | 	} else { | ||||||
|  | 		d = dirfstat(fd); | ||||||
|  | 		if(d == nil){ | ||||||
|  | 			e = PosixENOENT; | ||||||
|  | 		} else { | ||||||
|  | 			if((d->mode & DMDIR) == 0) | ||||||
|  | 				e = PosixENOTDIR; | ||||||
|  | 			free(d); | ||||||
|  | 			if(fd2path(fd, buf, sizeof(buf)) != 0) | ||||||
|  | 				e = PosixENOENT;	/* just removed? */ | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	if(e != 0) | ||||||
|  | 		goto FailWithError; | ||||||
|  |  | ||||||
|  | 	if(chdir(buf) == 0) | ||||||
|  | 		return 0; | ||||||
|  |  | ||||||
|  | 	*errnop = __libposix_translate_errstr((uintptr_t)POSIX_fchdir); | ||||||
|  | 	return -1; | ||||||
|  |  | ||||||
|  | FailWithError: | ||||||
|  | 	*errnop = __libposix_get_errno(e); | ||||||
|  | 	return -1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int | ||||||
|  | POSIX_mkdir(int *errnop, const char *path, int mode) | ||||||
|  | { | ||||||
|  | 	long cperm = 0; | ||||||
|  | 	PosixError e = 0; | ||||||
|  | 	int fd; | ||||||
|  |  | ||||||
|  | 	if(path == nil) | ||||||
|  | 		e = PosixEFAULT; | ||||||
|  | 	else if(access(path, AEXIST) == 0) | ||||||
|  | 		e = PosixEEXIST; | ||||||
|  | 	else | ||||||
|  | 		e = __libposix_open_translation(0, mode, nil, &cperm); | ||||||
|  | 	if(e != 0) | ||||||
|  | 		goto FailWithError; | ||||||
|  |  | ||||||
|  | 	fd = create(path, OREAD, DMDIR | cperm); | ||||||
|  | 	if(fd >= 0){ | ||||||
|  | 		close(fd); | ||||||
|  | 		return 0; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	*errnop = __libposix_translate_errstr((uintptr_t)POSIX_mkdir); | ||||||
|  | 	return -1; | ||||||
|  |  | ||||||
|  | FailWithError: | ||||||
|  | 	*errnop = __libposix_get_errno(e); | ||||||
|  | 	return -1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
| /* getdents is not POSIX, but is used in POSIX C library to implement | /* getdents is not POSIX, but is used in POSIX C library to implement | ||||||
|  * readdir. |  * readdir. | ||||||
|  */ |  */ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user