I'm looking at the man page for the libc function execve under Ubuntu 16.04.

I'm trying to handle errors as described by the man page:

RETURN VALUE
On success, execve() does not return, on error -1 is returned, and errno is set appropriately.

So I check below on the ERROR section and I see:

ERRORS
   ...
   EACCES Search permission is denied on a component of the path prefix of filename or the name of a script interpreter.  (See also path_resolution(7).)

   EACCES The file or a script interpreter is not a regular file.

   EACCES Execute permission is denied for the file or a script or ELF interpreter.

   EACCES The filesystem is mounted noexec.
   ....

Does this mean that EACCES could be any of these things? Or less likely all of them?

How can I tell them apart when handling errors from a switch statement?

up vote 2 down vote accepted

Does this mean that EACCES could be any of these things? Or less likely all of them?

Any. As for "all", if there's a path traversal error, how would code even be able to try other things such as the "is it a regular file" if the code lacks permission to traverse to the file? Also returning multiple errors is not really a thing C does by default (unless you wrote some struct that contains a list of errors and then a pointer to that struct is somehow gotten back to the caller who then needs to...and that's not how most system calls are written.)

How can I tell them apart when handling errors from a switch statement?

strerror(errno) or the nifty err(3) which doubtless in turn calls strerror is pretty much the most you'll get:

$ cat sirexecsalot.c
#include <err.h>
#include <string.h>
#include <unistd.h>
extern char **environ;
extern int errno;
int main(int argc, char *argv[])
{
    int ret;
    errno = 0;
    if ((ret = execve("/var/tmp/exectest/hullo", ++argv, environ)) == -1)
        err(1, "nope (strerr=%s)", strerror(errno));
}

$ make sirexecsalot
cc     sirexecsalot.c   -o sirexecsalot
$ cat /var/tmp/exectest/hullo
#!/usr/bin/env expect
puts hi

$ ./sirexecsalot
hi
$ mv /var/tmp/exectest/hullo /var/tmp/exectest/foo
$ mkdir /var/tmp/exectest/hullo
$ ./sirexecsalot              
sirexecsalot: nope (strerr=Permission denied): Permission denied
$ chmod 000 /var/tmp/exectest 
$ ./sirexecsalot             
sirexecsalot: nope (strerr=Permission denied): Permission denied
$ 
  • Great thanks! I had no idea about strerror or err, definitely useful functions! – gatoWololo Jul 13 '17 at 21:12
  • 2
    There is also perror() – Arkadiusz Drabczyk Jul 14 '17 at 14:21

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.