Error Handling#
The errno
Variable#
On error, system calls (and most C library functions)
return -1
set the global variable
errno
#include <fcntl.h>
#include <print>
int main()
{
int fd = open("/etc/passwd", O_RDWR);
if (fd == -1) {
std::println("open failed, errno=={}", errno);
return 1;
}
return 0;
}
$ ./sysprog-errors--return-and-errno
open failed, errno==13
errno
Is A Global Variable#
errno
is global, with all consequencesShould read it immediately after failed syscall
#include <fcntl.h>
#include <print>
int main()
{
int fd = open("/etc/passwd", O_RDWR);
if (fd == -1) {
std::println("open failed");
std::println("errno=={}", errno); // <-- errno could have changed by previous println()
return 1;
}
return 0;
}
Simplest Stringification: perror()
#
Advantage: need not mention
errno
Translates
errno
into a descriptive stringValue of
errno
not printed though
#include <fcntl.h>
#include <stdio.h>
int main()
{
int fd = open("/etc/passwd", O_RDWR);
if (fd == -1) {
perror("open failed");
return 1;
}
return 0;
}
$ ./sysprog-errors--perror
open failed: Permission denied
More Stringification: strerror()
#
Returns a pointer to a descriptive string
Does not print anything itself
Not thread-safe: pointer might be invalidated by subsequent calls to
strerror()
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <print>
int main()
{
int fd = open("/etc/passwd", O_RDWR);
if (fd == -1) {
const char* errstr = strerror(errno);
std::println("open failed: {} ({})", errstr, errno);
return 1;
}
return 0;
}
$ ./sysprog-errors--strerror
open failed: Permission denied (13)
Thread-Safe Stringification: strerror_r()
#
_r
for “reentrant”User has to supply buffer
Buffer might be used by
strerror_r()
Message might be truncated if buffer too small; always 0-terminated
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <print>
int main()
{
int fd = open("/etc/passwd", O_RDWR);
if (fd == -1) {
char buf[64]; // <-- *might* be used
const char* errstr = strerror_r(errno, buf, sizeof(buf));
std::println("open failed: {} ({})", errstr, errno);
return 1;
}
return 0;
}
$ ./sysprog-errors--strerror_r
open failed: Permission denied (13)