systemdにはPROTECT_ERRNOというマクロがある。使い方はこんな感じ。
src/shared/util.c
int unlink_noerrno(const char *path) {
PROTECT_ERRNO;
int r;
r = unlink(path);
if (r < 0)
return -errno;
return 0;
}
定義を見てみると、なるほどと思った。
src/shared/util.h
static inline void _reset_errno_(int *saved_errno) {
errno = *saved_errno;
}
# define PROTECT_ERRNO _cleanup_(_reset_errno_) __attribute__((unused)) int _saved_errno_ = errno
errnoを一旦保存して、関数を抜けるときに cleanup属性 を使って保存したerrnoを元に戻している。
上記の使用例だと、unlink(2)でerrnoが上書きされるのを防いでいるようだ。