On 01/25/2011 01:31 PM, Eric Blake wrote: > One other thing to point out - this is not the first time glibc has > added code around *at kernel syscalls in order to provide POSIX > semantics where the Linux syscall does not. Remember that both futimens > and utimensat are implemented on top of the same syscall, and that > futimens(AT_FDCWD, times) must fail rather than set the times on ".". I guess an executive summary of the issue, from my point of view, is that I like the idea of making both simple versions of a command call into the same *at version of the syscall [chmod via sys_fchmodat(AT_FDCWD,name), and fchmod via sys_fchmodat(fd, NULL)], provided that: 1. chmod("") must continue to fail with ENOENT (here, it might make sense for the kernel to do the filtering, since there is an obvious difference between "" and NULL; but if the kernel call does not change, then the burden is on glibc instead) 2. fchmod(AT_FDCWD) must continue to fail with EBADF (here, it might make sense for the kernel to do the filtering - if the name argument is NULL, then the fd argument must be non-negative; but precedence with futimens vs. sys_utimensat puts the burden on glibc instead) 3. chmod(NULL) is undefined. Currently it fails with EFAULT, but I see no reason why it can't start failing with EBADF (assuming the kernel does filtering as for point 2) or start operating on ".", because it's only a buggy program that would be making that call in the first place (actually, failing with EBADF is a little safer, as silent conversion between two types of failures is a bit easier to audit for consequences than is silent conversion from error to success). 4. fchmodat(fd, NULL) is undefined. For non-negative fd, POSIX allows failure, but it also allows behaving like fchmod. Portable programs can't rely on a particular behavior, but glibc is more than welcome to rely on a particular syscall behavior for implementing the simpler functions. 5. fchmodat(fd, "") must fail with ENOENT. For non-negative fd, apparently the kernel currently modifies fd, although point 1 says it might make more sense to fail with ENOENT so that glibc doesn't have to do as much work in chmod and fchmodat (if the kernel call does not change, then the burden is on glibc). 6. fchmodat(AT_FDCWD, NULL) is undefined. For AT_FDCWD, the kernel currently modifies ".", although point 2 says it might make more sense to fail with EBADF so that glibc doesn't have to do as much work in fchmod. 7. fchmodat(AT_FDCWD, "") must fail with ENOENT. Apparently, the kernel currently modifies ".", although point 1 says it might make more sense to fail with ENOENT so that glibc doesn't have to do as much work in chmod and fchmodat (if the kernel call does not change, then the burden is on glibc). -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org