github.com/afumu/libc@v0.0.6/musl/src/stat/fchmodat.c (about)

     1  #include <sys/stat.h>
     2  #include <fcntl.h>
     3  #include <errno.h>
     4  #include "syscall.h"
     5  #include "kstat.h"
     6  
     7  int fchmodat(int fd, const char *path, mode_t mode, int flag)
     8  {
     9  	if (!flag) return syscall(SYS_fchmodat, fd, path, mode, flag);
    10  
    11  	if (flag != AT_SYMLINK_NOFOLLOW)
    12  		return __syscall_ret(-EINVAL);
    13  
    14  	struct kstat st;
    15  	int ret, fd2;
    16  	char proc[15+3*sizeof(int)];
    17  
    18  	if ((ret = __syscall(SYS_fstatat, fd, path, &st, flag)))
    19  		return __syscall_ret(ret);
    20  	if (S_ISLNK(st.st_mode))
    21  		return __syscall_ret(-EOPNOTSUPP);
    22  
    23  	if ((fd2 = __syscall(SYS_openat, fd, path, O_RDONLY|O_PATH|O_NOFOLLOW|O_NOCTTY|O_CLOEXEC)) < 0) {
    24  		if (fd2 == -ELOOP)
    25  			return __syscall_ret(-EOPNOTSUPP);
    26  		return __syscall_ret(fd2);
    27  	}
    28  
    29  	__procfdname(proc, fd2);
    30  	ret = __syscall(SYS_fstatat, AT_FDCWD, proc, &st, 0);
    31  	if (!ret) {
    32  		if (S_ISLNK(st.st_mode)) ret = -EOPNOTSUPP;
    33  		else ret = __syscall(SYS_fchmodat, AT_FDCWD, proc, mode);
    34  	}
    35  
    36  	__syscall(SYS_close, fd2);
    37  	return __syscall_ret(ret);
    38  }