It appears that many programmers are unaware that there is a fundamental difference between the error codes
EACCES
(aka "Permission denied") and
EPERM
(aka "Operation not permitted"). In particular, a lot of code returns
EPERM
when they really mean
EACCES
:
mist% killall sshd
sshd(2244): Operation not permitted
To clear this up: "Permission denied" means just that -- the process has insufficient privileges to perform the requested operation. Simply put, this means that "trying the same thing as root will work". For instance, messing around with files you do not have the appropriate permissions to (i.e. in the
access(2)
sense) will get you
EACCES
:
mist% ls /root
ls: cannot open directory /root: Permission denied
On the other hand, "Operation not permitted" means the operation is
systematically not permissible; in other words it would be unwise for the system to perform the requested operation -- regardless of access privileges (think "I can't let you do that, Dave."). Usually, this means that either the operation is not supported (e.g.
chmod
ding a file residing on a FAT filesystem -- FAT simply does not support permission bits, there is nothing anyone can do about that) or it would endanger the integrity of the system (e.g. creating additional
hardlinks on a directory -- this would mess up the reference counting mechanism and result in "lost" disk space). Simply put, this means that "it cannot be done, not even as root".
So next time you write code signalling errors with the
E*
constants, think hard before choosing: Do user privileges play a role in whether or not the error will occur? If yes, use
EACCES
. If no, use
EPERM
.