diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/Plugins/CCpp.cpp | 27 | ||||
| -rw-r--r-- | lib/Utils/Makefile.am | 2 | ||||
| -rw-r--r-- | lib/Utils/logging.cpp | 119 | ||||
| -rw-r--r-- | lib/Utils/read_write.cpp | 93 | ||||
| -rw-r--r-- | lib/Utils/xfuncs.cpp | 214 |
5 files changed, 441 insertions, 14 deletions
diff --git a/lib/Plugins/CCpp.cpp b/lib/Plugins/CCpp.cpp index 1d442d6..c38f19b 100644 --- a/lib/Plugins/CCpp.cpp +++ b/lib/Plugins/CCpp.cpp @@ -18,6 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include "abrtlib.h" #include "CCpp.h" #include "ABRTException.h" @@ -26,16 +27,16 @@ #include "CommLayerInner.h" #include <fstream> #include <sstream> -#include <ctype.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <fcntl.h> -#include <stdlib.h> -#include <string.h> +//#include <ctype.h> +//#include <unistd.h> +//#include <sys/types.h> +//#include <sys/wait.h> +//#include <fcntl.h> +//#include <stdlib.h> +//#include <string.h> #include <iomanip> -#include <grp.h> -#include <pwd.h> +//#include <grp.h> +//#include <pwd.h> #include <nss.h> #include <sechash.h> @@ -537,16 +538,16 @@ void CAnalyzerCCpp::Init() { if (m_sOldCorePattern == CORE_PATTERN) { - fprintf(stderr, "warning: %s already contains %s, " - "did abrt daemon crash recently?\n", + log("warning: %s already contains %s, " + "did abrt daemon crash recently?", CORE_PATTERN_IFACE, CORE_PATTERN); /* There is no point in "restoring" CORE_PATTERN_IFACE * to CORE_PATTERN on exit. Will restore to a default value: */ m_sOldCorePattern = "core"; } - fprintf(stderr, "warning: %s was already set to run a crash analyser (%s), " - "abrt may interfere with it\b", + log("warning: %s was already set to run a crash analyser (%s), " + "abrt may interfere with it", CORE_PATTERN_IFACE, CORE_PATTERN); } diff --git a/lib/Utils/Makefile.am b/lib/Utils/Makefile.am index 0412e7e..fb4f578 100644 --- a/lib/Utils/Makefile.am +++ b/lib/Utils/Makefile.am @@ -1,5 +1,5 @@ lib_LTLIBRARIES = libABRTUtils.la -libABRTUtils_la_SOURCES = DebugDump.cpp DebugDump.h +libABRTUtils_la_SOURCES = DebugDump.cpp DebugDump.h logging.cpp read_write.cpp xfuncs.cpp libABRTUtils_la_LDFLAGS = -version-info 0:1:0 libABRTUtils_la_LIBADD = -lmagic libABRTUtils_la_CPPFLAGS = -I$(srcdir)/../../inc -I$(srcdir)/../../lib/CommLayer diff --git a/lib/Utils/logging.cpp b/lib/Utils/logging.cpp new file mode 100644 index 0000000..15104b8 --- /dev/null +++ b/lib/Utils/logging.cpp @@ -0,0 +1,119 @@ +/* + * Utility routines. + * + * Licensed under GPLv2, see file COPYING in this tarball for details. + */ +#include "abrtlib.h" +#include <syslog.h> + +int xfunc_error_retval = EXIT_FAILURE; + +void xfunc_die(void) +{ + exit(xfunc_error_retval); +} + +const char *msg_prefix = ""; +const char *msg_eol = "\n"; +int logmode = LOGMODE_STDIO; + +void verror_msg(const char *s, va_list p, const char* strerr) +{ + char *msg; + int prefix_len, strerr_len, msgeol_len, used; + + if (!logmode) + return; + + if (!s) /* nomsg[_and_die] uses NULL fmt */ + s = ""; /* some libc don't like printf(NULL) */ + + used = vasprintf(&msg, s, p); + if (used < 0) + return; + + /* This is ugly and costs +60 bytes compared to multiple + * fprintf's, but is guaranteed to do a single write. + * This is needed for e.g. when multiple children + * can produce log messages simultaneously. */ + + prefix_len = strlen(msg_prefix); + strerr_len = strerr ? strlen(strerr) : 0; + msgeol_len = strlen(msg_eol); + /* +3 is for ": " before strerr and for terminating NUL */ + msg = (char*) xrealloc(msg, prefix_len + used + strerr_len + msgeol_len + 3); + /* TODO: maybe use writev instead of memmoving? Need full_writev? */ + if (prefix_len) { + memmove(msg + prefix_len, msg, used); + used += prefix_len; + strcpy(msg, msg_prefix); + } + if (strerr) { + if (s[0]) { /* not perror_nomsg? */ + msg[used++] = ':'; + msg[used++] = ' '; + } + strcpy(&msg[used], strerr); + used += strerr_len; + } + strcpy(&msg[used], msg_eol); + + if (logmode & LOGMODE_STDIO) { + fflush(stdout); + full_write(STDERR_FILENO, msg, used + msgeol_len); + } + if (logmode & LOGMODE_SYSLOG) { + syslog(LOG_ERR, "%s", msg + prefix_len); + } + free(msg); +} + +void error_msg_and_die(const char *s, ...) +{ + va_list p; + + va_start(p, s); + verror_msg(s, p, NULL); + va_end(p); + xfunc_die(); +} + +void error_msg(const char *s, ...) +{ + va_list p; + + va_start(p, s); + verror_msg(s, p, NULL); + va_end(p); +} + +void perror_msg_and_die(const char *s, ...) +{ + va_list p; + + va_start(p, s); + /* Guard against "<error message>: Success" */ + verror_msg(s, p, errno ? strerror(errno) : NULL); + va_end(p); + xfunc_die(); +} + +void perror_msg(const char *s, ...) +{ + va_list p; + + va_start(p, s); + /* Guard against "<error message>: Success" */ + verror_msg(s, p, errno ? strerror(errno) : NULL); + va_end(p); +} + +void simple_perror_msg_and_die(const char *s) +{ + perror_msg_and_die("%s", s); +} + +void simple_perror_msg(const char *s) +{ + perror_msg("%s", s); +} diff --git a/lib/Utils/read_write.cpp b/lib/Utils/read_write.cpp new file mode 100644 index 0000000..38907aa --- /dev/null +++ b/lib/Utils/read_write.cpp @@ -0,0 +1,93 @@ +/* + * Utility routines. + * + * Licensed under GPLv2 or later, see file COPYING in this tarball for details. + */ +#include "abrtlib.h" + +ssize_t safe_read(int fd, void *buf, size_t count) +{ + ssize_t n; + + do { + n = read(fd, buf, count); + } while (n < 0 && errno == EINTR); + + return n; +} + +ssize_t full_read(int fd, void *buf, size_t len) +{ + ssize_t cc; + ssize_t total; + + total = 0; + + while (len) { + cc = safe_read(fd, buf, len); + + if (cc < 0) { + if (total) { + /* we already have some! */ + /* user can do another read to know the error code */ + return total; + } + return cc; /* read() returns -1 on failure. */ + } + if (cc == 0) + break; + buf = ((char *)buf) + cc; + total += cc; + len -= cc; + } + + return total; +} + +/* Die with an error message if we can't read the entire buffer. */ +void xread(int fd, void *buf, size_t count) +{ + if (count) { + ssize_t size = full_read(fd, buf, count); + if ((size_t)size != count) + error_msg_and_die("short read"); + } +} + +ssize_t safe_write(int fd, const void *buf, size_t count) +{ + ssize_t n; + + do { + n = write(fd, buf, count); + } while (n < 0 && errno == EINTR); + + return n; +} + +ssize_t full_write(int fd, const void *buf, size_t len) +{ + ssize_t cc; + ssize_t total; + + total = 0; + + while (len) { + cc = safe_write(fd, buf, len); + + if (cc < 0) { + if (total) { + /* we already wrote some! */ + /* user can do another write to know the error code */ + return total; + } + return cc; /* write() returns -1 on failure. */ + } + + total += cc; + buf = ((const char *)buf) + cc; + len -= cc; + } + + return total; +} diff --git a/lib/Utils/xfuncs.cpp b/lib/Utils/xfuncs.cpp new file mode 100644 index 0000000..ad67ec6 --- /dev/null +++ b/lib/Utils/xfuncs.cpp @@ -0,0 +1,214 @@ +/* + * Utility routines. + * + * Licensed under GPLv2, see file COPYING in this tarball for details. + */ +#include "abrtlib.h" + +static const char msg_memory_exhausted[] = "memory exhausted"; + +void* malloc_or_warn(size_t size) +{ + void *ptr = malloc(size); + if (ptr == NULL && size != 0) + error_msg(msg_memory_exhausted); + return ptr; +} + +// Die if we can't allocate size bytes of memory. +void* xmalloc(size_t size) +{ + void *ptr = malloc(size); + if (ptr == NULL && size != 0) + error_msg_and_die(msg_memory_exhausted); + return ptr; +} + +// Die if we can't resize previously allocated memory. (This returns a pointer +// to the new memory, which may or may not be the same as the old memory. +// It'll copy the contents to a new chunk and free the old one if necessary.) +void* xrealloc(void *ptr, size_t size) +{ + ptr = realloc(ptr, size); + if (ptr == NULL && size != 0) + error_msg_and_die(msg_memory_exhausted); + return ptr; +} + +// Die if we can't allocate and zero size bytes of memory. +void* xzalloc(size_t size) +{ + void *ptr = xmalloc(size); + memset(ptr, 0, size); + return ptr; +} + +// Die if we can't copy a string to freshly allocated memory. +char* xstrdup(const char *s) +{ + char *t; + + if (s == NULL) + return NULL; + + t = strdup(s); + + if (t == NULL) + error_msg_and_die(msg_memory_exhausted); + + return t; +} + +// Die if we can't allocate n+1 bytes (space for the null terminator) and copy +// the (possibly truncated to length n) string into it. +char* xstrndup(const char *s, int n) +{ + int m; + char *t; + + /* We can just xmalloc(n+1) and strncpy into it, */ + /* but think about xstrndup("abc", 10000) wastage! */ + m = n; + t = (char*) s; + while (m) { + if (!*t) break; + m--; + t++; + } + n -= m; + t = (char*) xmalloc(n + 1); + t[n] = '\0'; + + return (char*) memcpy(t, s, n); +} + +void xpipe(int filedes[2]) +{ + if (pipe(filedes)) + perror_msg_and_die("can't create pipe"); +} + +void xdup2(int from, int to) +{ + if (dup2(from, to) != to) + perror_msg_and_die("can't duplicate file descriptor"); +} + +// "Renumber" opened fd +void xmove_fd(int from, int to) +{ + if (from == to) + return; + xdup2(from, to); + close(from); +} + +// Die with an error message if we can't write the entire buffer. +void xwrite(int fd, const void *buf, size_t count) +{ + if (count) { + ssize_t size = full_write(fd, buf, count); + if ((size_t)size != count) + error_msg_and_die("short write"); + } +} +void xwrite_str(int fd, const char *str) +{ + xwrite(fd, str, strlen(str)); +} + +// Die with an error message if we can't lseek to the right spot. +off_t xlseek(int fd, off_t offset, int whence) +{ + off_t off = lseek(fd, offset, whence); + if (off == (off_t)-1) { + if (whence == SEEK_SET) + perror_msg_and_die("lseek(%llu)", (long long)offset); + perror_msg_and_die("lseek"); + } + return off; +} + +// Die with an error message if we can't malloc() enough space and do an +// sprintf() into that space. +char* xasprintf(const char *format, ...) +{ + va_list p; + int r; + char *string_ptr; + +#if 1 + // GNU extension + va_start(p, format); + r = vasprintf(&string_ptr, format, p); + va_end(p); +#else + // Bloat for systems that haven't got the GNU extension. + va_start(p, format); + r = vsnprintf(NULL, 0, format, p); + va_end(p); + string_ptr = xmalloc(r+1); + va_start(p, format); + r = vsnprintf(string_ptr, r+1, format, p); + va_end(p); +#endif + + if (r < 0) + error_msg_and_die(msg_memory_exhausted); + return string_ptr; +} + +void xsetenv(const char *key, const char *value) +{ + if (setenv(key, value, 1)) + error_msg_and_die(msg_memory_exhausted); +} + +// Die with an error message if we can't open a new socket. +int xsocket(int domain, int type, int protocol) +{ + int r = socket(domain, type, protocol); + + if (r < 0) { + /* Hijack vaguely related config option */ + const char *s = "INET"; + if (domain == AF_PACKET) s = "PACKET"; + if (domain == AF_NETLINK) s = "NETLINK"; + if (domain == AF_INET6) s = "INET6"; + perror_msg_and_die("socket(AF_%s)", s); + } + + return r; +} + +// Die with an error message if we can't bind a socket to an address. +void xbind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen) +{ + if (bind(sockfd, my_addr, addrlen)) perror_msg_and_die("bind"); +} + +// Die with an error message if we can't listen for connections on a socket. +void xlisten(int s, int backlog) +{ + if (listen(s, backlog)) perror_msg_and_die("listen"); +} + +// Die with an error message if sendto failed. +// Return bytes sent otherwise +ssize_t xsendto(int s, const void *buf, size_t len, const struct sockaddr *to, + socklen_t tolen) +{ + ssize_t ret = sendto(s, buf, len, 0, to, tolen); + if (ret < 0) { + close(s); + perror_msg_and_die("sendto"); + } + return ret; +} + +// xstat() - a stat() which dies on failure with meaningful error message +void xstat(const char *name, struct stat *stat_buf) +{ + if (stat(name, stat_buf)) + perror_msg_and_die("can't stat '%s'", name); +} |
