libposix: drafted chdir, fchdir and mkdir

This commit is contained in:
Giacomo Tesio 2017-08-23 04:05:31 +02:00
parent 4de95c9bc0
commit bfb95a3d3e
2 changed files with 101 additions and 0 deletions

View File

@ -89,6 +89,9 @@ typedef unsigned long clock_t;
extern void POSIX_exit(int code) __attribute__((noreturn));
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_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_execve(int *errnop, const char *name, char * const*argv, char * const*env);
extern int POSIX_fork(int *errnop);

View File

@ -475,6 +475,104 @@ FailWithError:
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
* readdir.
*/