libposix: drafted chmod/fchmod; TODO: configurable AT_FDCWD
This commit is contained in:
parent
6a94e587a6
commit
4455658796
|
@ -332,8 +332,7 @@ POSIX_fstat(int *errnop, int file, void *pstat)
|
||||||
}
|
}
|
||||||
OnIgnoredSignalInterrupt:
|
OnIgnoredSignalInterrupt:
|
||||||
d = dirfstat(file);
|
d = dirfstat(file);
|
||||||
if(d == nil)
|
if(d == nil){
|
||||||
{
|
|
||||||
if(__libposix_restart_syscall())
|
if(__libposix_restart_syscall())
|
||||||
goto OnIgnoredSignalInterrupt;
|
goto OnIgnoredSignalInterrupt;
|
||||||
*errnop = __libposix_translate_errstr((uintptr_t)POSIX_fstat);
|
*errnop = __libposix_translate_errstr((uintptr_t)POSIX_fstat);
|
||||||
|
@ -361,8 +360,7 @@ POSIX_stat(int *errnop, const char *file, void *pstat)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
d = dirstat(file);
|
d = dirstat(file);
|
||||||
if(d == nil)
|
if(d == nil){
|
||||||
{
|
|
||||||
*errnop = __libposix_translate_errstr((uintptr_t)POSIX_stat);
|
*errnop = __libposix_translate_errstr((uintptr_t)POSIX_stat);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -377,21 +375,103 @@ POSIX_stat(int *errnop, const char *file, void *pstat)
|
||||||
int
|
int
|
||||||
POSIX_chmod(int *errnop, const char *path, int mode)
|
POSIX_chmod(int *errnop, const char *path, int mode)
|
||||||
{
|
{
|
||||||
|
Dir *dir, ndir;
|
||||||
long cperm = 0;
|
long cperm = 0;
|
||||||
PosixError e;
|
PosixError e;
|
||||||
|
|
||||||
e = __libposix_open_translation(0, mode, nil, &cperm);
|
if(path == nil)
|
||||||
if(e != 0){
|
e = PosixENOENT;
|
||||||
*errnop = __libposix_get_errno(e);
|
else
|
||||||
|
e = __libposix_open_translation(0, mode, nil, &cperm);
|
||||||
|
if(e != 0)
|
||||||
|
goto FailWithError;
|
||||||
|
dir = dirstat(path);
|
||||||
|
if(dir == nil){
|
||||||
|
e = PosixENOENT;
|
||||||
|
goto FailWithError;
|
||||||
|
}
|
||||||
|
nulldir(&ndir);
|
||||||
|
ndir.mode = (dir->mode & ~(0777)) | (cperm & 0777);
|
||||||
|
free(dir);
|
||||||
|
|
||||||
|
if(dirwstat(path, &ndir) < 0){
|
||||||
|
*errnop = __libposix_translate_errstr((uintptr_t)POSIX_chmod);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
FailWithError:
|
||||||
|
*errnop = __libposix_get_errno(e);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
POSIX_fchmodat(int *errnop, int fd, const char *path, long mode, int flag)
|
POSIX_fchmodat(int *errnop, int fd, const char *path, long mode, int flag)
|
||||||
{
|
{
|
||||||
|
#define AT_FDCWD -100 /* from NetBSD; TODO: get from configuration */
|
||||||
|
Dir *dir, ndir;
|
||||||
|
long cperm = 0;
|
||||||
|
char fullpath[4096], *p;
|
||||||
|
int l;
|
||||||
|
PosixError e;
|
||||||
|
|
||||||
|
if(fd == AT_FDCWD){
|
||||||
|
return POSIX_chmod(errnop, path, mode);
|
||||||
|
} else if(path == nil){
|
||||||
|
e = PosixENOENT;
|
||||||
|
} else if(strlen(path) > sizeof(fullpath)-100){
|
||||||
|
e = PosixENAMETOOLONG;
|
||||||
|
} else if(path[0] == '/'){
|
||||||
|
if(fd < 0)
|
||||||
|
e = PosixEBADF;
|
||||||
|
else {
|
||||||
|
dir = dirfstat(fd);
|
||||||
|
if(dir == nil){
|
||||||
|
e = PosixEBADF;
|
||||||
|
} else {
|
||||||
|
if((dir->mode & DMDIR) == 0)
|
||||||
|
e = PosixENOTDIR;
|
||||||
|
free(dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
e = __libposix_open_translation(0, mode, nil, &cperm);
|
||||||
|
}
|
||||||
|
if(e == 0 && fd2path(fd, fullpath, sizeof(fullpath)-2) != 0)
|
||||||
|
e = PosixEBADF;
|
||||||
|
if(e != 0)
|
||||||
|
goto FailWithError;
|
||||||
|
|
||||||
|
l = strlen(fullpath);
|
||||||
|
fullpath[l++] = '/';
|
||||||
|
p = fullpath + l;
|
||||||
|
l = strlen(path);
|
||||||
|
if(l > sizeof(fullpath) - (p - fullpath) - 1){
|
||||||
|
e = PosixENAMETOOLONG;
|
||||||
|
goto FailWithError;
|
||||||
|
}
|
||||||
|
strncpy(p, path, strlen(path)+1);
|
||||||
|
cleanname(fullpath);
|
||||||
|
|
||||||
|
dir = dirstat(path);
|
||||||
|
if(dir == nil){
|
||||||
|
e = PosixENOENT;
|
||||||
|
goto FailWithError;
|
||||||
|
}
|
||||||
|
nulldir(&ndir);
|
||||||
|
ndir.mode = (dir->mode & ~(0777)) | (cperm & 0777);
|
||||||
|
free(dir);
|
||||||
|
|
||||||
|
if(dirwstat(path, &ndir) < 0){
|
||||||
|
*errnop = __libposix_translate_errstr((uintptr_t)POSIX_chmod);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
FailWithError:
|
||||||
|
*errnop = __libposix_get_errno(e);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue