/* * * Conky, a system monitor, based on torsmo * * Please see COPYING for details * * Copyright (C) 2010 Pavel Labath et al. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #include "config.h" #include "c++wrap.hh" #include #include /* force use of POSIX strerror_r instead of non-portable GNU specific */ #ifdef _GNU_SOURCE #undef _GNU_SOURCE #endif #include #if __cplusplus <= 199711L #define thread_local __thread #endif #if !defined(HAVE_PIPE2) || !defined(HAVE_O_CLOEXEC) #include namespace { int pipe2_emulate(int pipefd[2], int flags) { if (pipe(pipefd) == -1) { return -1; } if ((flags & O_CLOEXEC) != 0) { // we emulate O_CLOEXEC if the system does not have it // not very thread-safe, but at least it works for (int i = 0; i < 2; ++i) { int r = fcntl(pipefd[i], F_GETFD); if (r == -1) { return -1; } if (fcntl(pipefd[i], F_SETFD, r | FD_CLOEXEC) == -1) { return -1; } } } return 0; } int (*const pipe2_ptr)(int[2], int) = &pipe2_emulate; } // namespace #else int (*const pipe2_ptr)(int[2], int) = &pipe2; #endif std::string strerror_r(int errnum) { static thread_local char buf[100]; if (strerror_r(errnum, buf, sizeof buf) != 0) { snprintf(buf, sizeof buf, "Unknown error %i", errnum); } return buf; } std::pair pipe2(int flags) { int fd[2]; if (pipe2_ptr(fd, flags) == -1) { throw errno_error("pipe2"); } { return std::pair(fd[0], fd[1]); } }