Update blkid to 2.25.0
Break libblkid into 4 libraries: libblkid, libuuid, libutil-linux and libfdisk.

This should help in later patch updates.

Change-Id: I680d9a7feb031e5c29a603e9c58aff4b65826262
diff --git a/libblkid/lib/procutils.c b/libblkid/lib/procutils.c
new file mode 100644
index 0000000..ef96941
--- /dev/null
+++ b/libblkid/lib/procutils.c
@@ -0,0 +1,264 @@
+/*
+ * Copyright (C) 2011 Davidlohr Bueso <dave@gnu.org>
+ *
+ * procutils.c: General purpose procfs parsing utilities
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Library Public License as published by
+ * the Free Software Foundation; either version 2, 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 Library Public License for more details.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <ctype.h>
+
+#include "procutils.h"
+#include "at.h"
+#include "c.h"
+
+/*
+ * @pid: process ID for which we want to obtain the threads group
+ *
+ * Returns: newly allocated tasks structure
+ */
+struct proc_tasks *proc_open_tasks(pid_t pid)
+{
+	struct proc_tasks *tasks;
+	char path[PATH_MAX];
+
+	sprintf(path, "/proc/%d/task/", pid);
+
+	tasks = malloc(sizeof(struct proc_tasks));
+	if (tasks) {
+		tasks->dir = opendir(path);
+		if (tasks->dir)
+			return tasks;
+	}
+
+	free(tasks);
+	return NULL;
+}
+
+/*
+ * @tasks: allocated tasks structure
+ *
+ * Returns: nothing
+ */
+void proc_close_tasks(struct proc_tasks *tasks)
+{
+	if (tasks && tasks->dir)
+		closedir(tasks->dir);
+	free(tasks);
+}
+
+/*
+ * @tasks: allocated task structure
+ * @tid: [output] one of the thread IDs belonging to the thread group
+ *        If when an error occurs, it is set to 0.
+ *
+ * Returns: 0 on success, 1 on end, -1 on failure or no more threads
+ */
+int proc_next_tid(struct proc_tasks *tasks, pid_t *tid)
+{
+	struct dirent *d;
+	char *end;
+
+	if (!tasks || !tid)
+		return -EINVAL;
+
+	*tid = 0;
+	errno = 0;
+
+	do {
+		d = readdir(tasks->dir);
+		if (!d)
+			return errno ? -1 : 1;		/* error or end-of-dir */
+
+		if (!isdigit((unsigned char) *d->d_name))
+			continue;
+		errno = 0;
+		*tid = (pid_t) strtol(d->d_name, &end, 10);
+		if (errno || d->d_name == end || (end && *end))
+			return -1;
+
+	} while (!*tid);
+
+	return 0;
+}
+
+struct proc_processes *proc_open_processes(void)
+{
+	struct proc_processes *ps;
+
+	ps = calloc(1, sizeof(struct proc_processes));
+	if (ps) {
+		ps->dir = opendir("/proc");
+		if (ps->dir)
+			return ps;
+	}
+
+	free(ps);
+	return NULL;
+}
+
+void proc_close_processes(struct proc_processes *ps)
+{
+	if (ps && ps->dir)
+		closedir(ps->dir);
+	free(ps);
+}
+
+void proc_processes_filter_by_name(struct proc_processes *ps, const char *name)
+{
+	ps->fltr_name = name;
+	ps->has_fltr_name = name ? 1 : 0;
+}
+
+void proc_processes_filter_by_uid(struct proc_processes *ps, uid_t uid)
+{
+	ps->fltr_uid = uid;
+	ps->has_fltr_uid = 1;
+}
+
+int proc_next_pid(struct proc_processes *ps, pid_t *pid)
+{
+	struct dirent *d;
+
+	if (!ps || !pid)
+		return -EINVAL;
+
+	*pid = 0;
+	errno = 0;
+
+	do {
+		char buf[BUFSIZ], *p;
+
+		d = readdir(ps->dir);
+		if (!d)
+			return errno ? -1 : 1;		/* error or end-of-dir */
+
+
+		if (!isdigit((unsigned char) *d->d_name))
+			continue;
+
+		/* filter out by UID */
+		if (ps->has_fltr_uid) {
+			struct stat st;
+
+			if (fstat_at(dirfd(ps->dir), "/proc", d->d_name, &st, 0))
+				continue;
+			if (ps->fltr_uid != st.st_uid)
+				continue;
+		}
+
+		/* filter out by NAME */
+		if (ps->has_fltr_name) {
+			char procname[256];
+			FILE *f;
+
+			snprintf(buf, sizeof(buf), "%s/stat", d->d_name);
+			f = fopen_at(dirfd(ps->dir), "/proc", buf,
+						O_CLOEXEC|O_RDONLY, "r");
+			if (!f)
+				continue;
+
+			p = fgets(buf, sizeof(buf), f);
+			fclose(f);
+			if (!p)
+				continue;
+
+			if (sscanf(buf, "%*d (%255[^)])", procname) != 1)
+				continue;
+
+			/* ok, we got the process name. */
+			if (strcmp(procname, ps->fltr_name) != 0)
+				continue;
+		}
+
+		p = NULL;
+		errno = 0;
+		*pid = (pid_t) strtol(d->d_name, &p, 10);
+		if (errno || d->d_name == p || (p && *p))
+			return errno ? -errno : -1;
+
+		return 0;
+	} while (1);
+
+	return 0;
+}
+
+#ifdef TEST_PROGRAM
+
+static int test_tasks(int argc, char *argv[])
+{
+	pid_t tid, pid;
+	struct proc_tasks *ts;
+
+	if (argc != 2)
+		return EXIT_FAILURE;
+
+	pid = strtol(argv[1], (char **) NULL, 10);
+	printf("PID=%d, TIDs:", pid);
+
+	ts = proc_open_tasks(pid);
+	if (!ts)
+		err(EXIT_FAILURE, "open list of tasks failed");
+
+	while (proc_next_tid(ts, &tid) == 0)
+		printf(" %d", tid);
+
+	printf("\n");
+        proc_close_tasks(ts);
+	return EXIT_SUCCESS;
+}
+
+static int test_processes(int argc, char *argv[])
+{
+	pid_t pid;
+	struct proc_processes *ps;
+
+	ps = proc_open_processes();
+	if (!ps)
+		err(EXIT_FAILURE, "open list of processes failed");
+
+	if (argc >= 3 && strcmp(argv[1], "--name") == 0)
+		proc_processes_filter_by_name(ps, argv[2]);
+
+	if (argc >= 3 && strcmp(argv[1], "--uid") == 0)
+		proc_processes_filter_by_uid(ps, (uid_t) atol(argv[2]));
+
+	while (proc_next_pid(ps, &pid) == 0)
+		printf(" %d", pid);
+
+	printf("\n");
+        proc_close_processes(ps);
+	return EXIT_SUCCESS;
+}
+
+int main(int argc, char *argv[])
+{
+	if (argc < 2) {
+		fprintf(stderr, "usage: %1$s --tasks <pid>\n"
+				"       %1$s --processes [---name <name>] [--uid <uid>]\n",
+				program_invocation_short_name);
+		return EXIT_FAILURE;
+	}
+
+	if (strcmp(argv[1], "--tasks") == 0)
+		return test_tasks(argc - 1, argv + 1);
+	if (strcmp(argv[1], "--processes") == 0)
+		return test_processes(argc - 1, argv + 1);
+
+	return EXIT_FAILURE;
+}
+#endif /* TEST_PROGRAM */