summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Plugins/CCpp.cpp27
-rw-r--r--lib/Utils/Makefile.am2
-rw-r--r--lib/Utils/logging.cpp119
-rw-r--r--lib/Utils/read_write.cpp93
-rw-r--r--lib/Utils/xfuncs.cpp214
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);
+}