public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-commits] gentoo-projects commit in portage-utils/libq: libq.c md5_sha1_sum.c prelink.c
@ 2011-10-03  0:24 Mike Frysinger (vapier)
  0 siblings, 0 replies; only message in thread
From: Mike Frysinger (vapier) @ 2011-10-03  0:24 UTC (permalink / raw
  To: gentoo-commits

vapier      11/10/03 00:24:22

  Modified:             libq.c md5_sha1_sum.c
  Added:                prelink.c
  Log:
  add prelink support to qcheck; patch based heavily on Martin von Gagern's work #369227

Revision  Changes    Path
1.25                 portage-utils/libq/libq.c

file : http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils/libq/libq.c?rev=1.25&view=markup
plain: http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils/libq/libq.c?rev=1.25&content-type=text/plain
diff : http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils/libq/libq.c?r1=1.24&r2=1.25

Index: libq.c
===================================================================
RCS file: /var/cvsroot/gentoo-projects/portage-utils/libq/libq.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -r1.24 -r1.25
--- libq.c	2 Mar 2011 07:03:31 -0000	1.24
+++ libq.c	3 Oct 2011 00:24:22 -0000	1.25
@@ -32,6 +32,7 @@
 #include "atom_explode.c"
 #include "atom_compare.c"
 #include "basename.c"
+#include "prelink.c"
 
 #ifndef _LIB_Q
 # include "profile.c"



1.8                  portage-utils/libq/md5_sha1_sum.c

file : http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils/libq/md5_sha1_sum.c?rev=1.8&view=markup
plain: http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils/libq/md5_sha1_sum.c?rev=1.8&content-type=text/plain
diff : http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils/libq/md5_sha1_sum.c?r1=1.7&r2=1.8

Index: md5_sha1_sum.c
===================================================================
RCS file: /var/cvsroot/gentoo-projects/portage-utils/libq/md5_sha1_sum.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- md5_sha1_sum.c	23 Feb 2011 22:58:52 -0000	1.7
+++ md5_sha1_sum.c	3 Oct 2011 00:24:22 -0000	1.8
@@ -29,9 +29,10 @@
 
 #include "busybox.h"
 
-#define FLAG_SILENT	1
-#define FLAG_CHECK	2
-#define FLAG_WARN	4
+/* pass in a fd and get back a fd; filename is for display only */
+typedef int (*hash_cb_t) (int, const char *);
+
+static int hash_cb_default(int fd, const char *filename) { return fd; }
 
 /* This might be useful elsewhere */
 static unsigned char *hash_bin_to_hex(unsigned char *hash_value,
@@ -48,24 +49,35 @@
 	return (hex_value);
 }
 
-static unsigned char *hash_file_at(int dfd, const char *filename, uint8_t hash_algo)
+static unsigned char *hash_file_at_cb(int dfd, const char *filename, uint8_t hash_algo, hash_cb_t cb)
 {
 	int fd;
-	fd = openat(dfd, filename, O_RDONLY);
+	fd = openat(dfd, filename, O_RDONLY|O_CLOEXEC);
 	if (fd != -1) {
 		static uint8_t hash_value_bin[20];
 		static unsigned char *hash_value;
-		hash_value =
-			(hash_fd(fd, -1, hash_algo, hash_value_bin) != -2 ?
-			 hash_bin_to_hex(hash_value_bin, hash_algo == HASH_MD5 ? 16 : 20) :
-			 NULL);
+		fd = cb(fd, filename);
+		if (hash_fd(fd, -1, hash_algo, hash_value_bin) != -2)
+			hash_value = hash_bin_to_hex(hash_value_bin, hash_algo == HASH_MD5 ? 16 : 20);
+		else
+			hash_value = NULL;
 		close(fd);
 		return hash_value;
 	}
 	return NULL;
 }
 
+static unsigned char *hash_file_at(int dfd, const char *filename, uint8_t hash_algo)
+{
+	return hash_file_at_cb(dfd, filename, hash_algo, hash_cb_default);
+}
+
+static unsigned char *hash_file_cb(const char *filename, uint8_t hash_algo, hash_cb_t cb)
+{
+	return hash_file_at_cb(AT_FDCWD, filename, hash_algo, cb);
+}
+
 static unsigned char *hash_file(const char *filename, uint8_t hash_algo)
 {
-	return hash_file_at(AT_FDCWD, filename, hash_algo);
+	return hash_file_cb(filename, hash_algo, hash_cb_default);
 }



1.1                  portage-utils/libq/prelink.c

file : http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils/libq/prelink.c?rev=1.1&view=markup
plain: http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils/libq/prelink.c?rev=1.1&content-type=text/plain

Index: prelink.c
===================================================================
/*
 * Copyright 2011 Gentoo Foundation
 * Distributed under the terms of the GNU General Public License v2
 * $Header: /var/cvsroot/gentoo-projects/portage-utils/libq/prelink.c,v 1.1 2011/10/03 00:24:22 vapier Exp $
 */

static const char prelink_bin[] = "prelink";

static int prelink_in_current_path(bool quiet_missing)
{
	pid_t pid;

	switch ((pid = fork())) {
	case -1: errp("error forking process");
	case 0: {
		/* we are the child */
		int dev_null;
		close(STDOUT_FILENO);
		dev_null = open("/dev/null", O_WRONLY);
		if (dev_null == -1) {
			warnp("Error opening /dev/null");
			_exit(2);
		}
		if (dup2(dev_null, STDOUT_FILENO) == -1) {
			warnp("Error redirecting output");
			_exit(2);
		}
		execlp(prelink_bin, prelink_bin, "--version", NULL);
		if (!quiet_missing || errno != ENOENT)
			warnp("error executing %s", prelink_bin);
		_exit(errno == ENOENT ? 1 : 2);
	}
	default: {
		/* we are the parent */
		int status;
		waitpid(pid, &status, 0);
		if (WIFEXITED(status))
			return MIN(WEXITSTATUS(status), 2);
		else
			errp("%s freaked out %#x", prelink_bin, status);
	}
	}
}

static bool prelink_available(void)
{
	int status = prelink_in_current_path(true);

	if (status == 1) {
		/* extend path to include sbin and search again */
		static const char sbin_path[] = "/sbin:/usr/sbin:/usr/local/sbin";
		char *path;
		xasprintf(&path, "PATH=%s:%s", getenv("PATH") ? : "", sbin_path);
		putenv(path);
		status = prelink_in_current_path(0);
	}

	return status == 0 ? true : false;
}

#ifdef __linux__
#include <elf.h>
static bool is_elf(int fd, const char *filename)
{
	char header[SELFMAG];
	ssize_t len;

	len = read(fd, &header, sizeof(header));
	if (len == -1) {
		warnp("unable to read %s", filename);
		return false;
	}
	if (lseek(fd, 0, SEEK_SET) != 0)
		errp("unable to reset after ELF check %s\n", filename);
	if (len < sizeof(header))
		return false;

	return memcmp(header, ELFMAG, sizeof(header)) == 0 ? true : false;
}
#else
static bool is_elf(int fd, const char *filename)
{
	return false;
}
#endif

static int execvp_const(const char * const argv[])
{
	return execvp(argv[0], (void *)argv);
}

static int _hash_cb_prelink(int fd, const char *filename, const char * const argv[])
{
	int pipefd[2];

	if (!is_elf(fd, filename))
		return fd;

	if (pipe(pipefd))
		errp("unable to create pipe");

	switch (fork()) {
	case -1: errp("error forking process");
	case 0: {
		/* we are the child */
		static const char * const cat_argv[] = { "cat", NULL, };
		pid_t pid;

		/* make sure we get notified of the child exit */
		signal(SIGCHLD, SIG_DFL);

		/* connect up stdin/stdout for reading/writing the file */
		close(pipefd[0]);
		if (dup2(fd, STDIN_FILENO) == -1) {
			warnp("error redirecting input");
			_exit(EXIT_FAILURE);
		}
		if (dup2(pipefd[1], STDOUT_FILENO) == -1) {
			warnp("error redirecting output");
			_exit(EXIT_FAILURE);
		}

		/*
		 * fork a monitor process ... this way the main qcheck program
		 * can simply read their side of the pipe without having to wait
		 * for the whole prelink program to run.  gives a bit of speed
		 * up on multicore systems and doesn't need as much mem to hold
		 * all the data in the pipe before we read it.  this also makes
		 * it easy to fall back to `cat` when prelink skipped the file
		 * that we fed it (like the split debug files).
		 */
		switch ((pid = fork())) {
		case -1: errp("error forking process");
		case 0:
			/* we are the child */
			execvp_const(argv);
			warnp("error executing %s", prelink_bin);
			_exit(1);
		default: {
			int status;
			waitpid(pid, &status, 0);
			if (WIFEXITED(status)) {
				if (WEXITSTATUS(status) == EXIT_SUCCESS)
					_exit(0);
				/* assume prelink printed its own error message */
			} else
				warnp("%s freaked out %#x", argv[0], status);
			/* we've come too far!  try one last thing ... */
			execvp_const(cat_argv);
			_exit(1);
		}
		}
	}
	default:
		/* we are the parent */
		close(pipefd[1]);
		/* we don't need this anymore since we've got a pipe to read */
		close(fd);
		/* ignore the monitor process exit status to avoid ZOMBIES */
		signal(SIGCHLD, SIG_IGN);
		/* assume child worked ... if it didn't, it will warn for us */
		return pipefd[0];
	}

	return fd;
}

static int hash_cb_prelink_undo(int fd, const char *filename)
{
	static const char * const argv[] = {
		prelink_bin,
		"--undo",
		"--undo-output=-",
		"/dev/stdin",
		NULL,
	};
	return _hash_cb_prelink(fd, filename, argv);
}






^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2011-10-03  0:24 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-10-03  0:24 [gentoo-commits] gentoo-projects commit in portage-utils/libq: libq.c md5_sha1_sum.c prelink.c Mike Frysinger (vapier)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox