[pacman-dev] [PATCH 5/5] Add QNX operating system specific implementations to libalpm and pacman.

Will Miles wmiles at sgl.com
Thu Feb 26 22:04:13 UTC 2015


Signed-off-by: Will Miles <wmiles at sgl.com>
---
 lib/libalpm/diskspace.c | 38 +++++++++++++++++++++++++++
 lib/libalpm/trans.c     | 37 +++++++++++++++++++++++++++
 lib/libalpm/util.c      | 68 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/pacman/pacman.c     |  4 +++
 4 files changed, 147 insertions(+)

diff --git a/lib/libalpm/diskspace.c b/lib/libalpm/diskspace.c
index 3b496c2..5142d05 100644
--- a/lib/libalpm/diskspace.c
+++ b/lib/libalpm/diskspace.c
@@ -119,6 +119,44 @@ static alpm_list_t *mount_point_list(alpm_handle_t *handle)
 	}
 
 	endmntent(fp);
+#elif defined(__QNX__)
+	/* QNX */
+	/* This is done the long way via a system command */
+	/* TODO: use the /proc calls directly */
+	char buffer[_POSIX_PATH_MAX];
+	FILE *cmd = popen("mount | cut -d ' ' -f 3", "r");
+
+	if (cmd == NULL) {
+		_alpm_log(handle, ALPM_LOG_WARNING, "Failed to get mount list: %s", strerror(errno));
+		return NULL;
+	}
+
+	memset(buffer, '\0', _POSIX_PATH_MAX);
+
+	while (fgets(buffer, _POSIX_PATH_MAX-1, cmd)) {
+		struct statvfs fsp;
+
+		/* eat trailing newline */
+		buffer[strlen(buffer) - 1] = '\0';
+
+		if(statvfs(buffer, &fsp) != 0) {
+			_alpm_log(handle, ALPM_LOG_WARNING,
+					_("could not get filesystem information for %s: %s\n"),
+					buffer, strerror(errno));
+			continue;
+		}
+
+
+		CALLOC(mp, 1, sizeof(alpm_mountpoint_t), RET_ERR(handle, ALPM_ERR_MEMORY, NULL));
+		mp->mount_dir = strdup(buffer);
+		mp->mount_dir_len = strlen(mp->mount_dir);
+		memcpy(&(mp->fsp), &fsp, sizeof(struct statvfs));
+		mp->read_only = fsp.f_flag & ST_RDONLY;
+
+		mount_points = alpm_list_add(mount_points, mp);
+	}
+
+	pclose(cmd);
 #elif defined(HAVE_GETMNTENT) && defined(HAVE_MNTTAB_H)
 	/* Solaris, Illumos */
 	struct mnttab mnt;
diff --git a/lib/libalpm/trans.c b/lib/libalpm/trans.c
index 6a26e75..1c8196c 100644
--- a/lib/libalpm/trans.c
+++ b/lib/libalpm/trans.c
@@ -41,6 +41,43 @@
 #include "alpm.h"
 #include "deps.h"
 
+#ifdef __QNX__
+/* supply a workaround implementation of mkdtemp as the system does not */
+static char *mkdtemp(char *templateName)
+{
+	static const char letters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+
+	const int length = strlen(templateName);
+
+	char *XXXXXX = templateName + length - 6;
+
+ 	if ((length < 6) || strncmp(XXXXXX, "XXXXXX", 6))
+		return 0;
+
+	for (int i = 0; i < 256; ++i) {
+		int v = rand();
+
+		/* Fill in the random bits.  */
+		XXXXXX[0] = letters[v % 62];
+		v /= 62;
+		XXXXXX[1] = letters[v % 62];
+		v /= 62;
+		XXXXXX[2] = letters[v % 62];
+		v /= 62;
+		XXXXXX[3] = letters[v % 62];
+		v /= 62;
+		XXXXXX[4] = letters[v % 62];
+		v /= 62;
+		XXXXXX[5] = letters[v % 62];
+
+		if (!mkdir(templateName, 0700))
+			return templateName;
+	}
+
+	return 0;
+}
+#endif
+
 /** \addtogroup alpm_trans Transaction Functions
  * @brief Functions to manipulate libalpm transactions
  * @{
diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c
index 4d85132..5e246df 100644
--- a/lib/libalpm/util.c
+++ b/lib/libalpm/util.c
@@ -89,6 +89,68 @@ char *strsep(char **str, const char *delims)
 }
 #endif
 
+#ifdef __QNX__
+/** QNX execv workaround
+ * On QNX, we must ensure that the loader is present and the pipe server is
+ * started in our chroot environment.  This function ensures that these
+ * services are correctly set up and torn down.
+ */
+int qnx_execv(const char *cmd, char *const argv[])
+{
+	int result;
+	int linked_loader = 0;
+	int started_pipe_server = 0;
+	struct stat stat_tmp;
+
+	/* Check to see if the loader exists; if not, link it */
+	if (stat("/usr/lib/ldqnx.so.2", &stat_tmp) != 0) {
+		result = link("/lib/libc.so.3","/usr/lib/ldqnx.so.2");
+		if (result != 0) {
+			fprintf(stderr, _("call to link loader failed (%s)\n"), strerror(errno));
+			exit(1);
+		}
+		linked_loader = 1;
+	};
+
+	/* Check to see if the pipe server is running; if not, start it */
+	/* Be aware that this clones the pipe fds to the pipe server, ie it is not 'fully' daemonized */
+	/* This means that the pacman host process will hang until the pipe server is terminated. */
+	if (stat("/dev/pipe", &stat_tmp) != 0) {
+		started_pipe_server = spawnl(P_NOWAIT,"/sbin/pipe","pipe",NULL);
+		if (started_pipe_server == -1) {
+			fprintf(stderr, _("call to start pipe server failed (%s)\n"), strerror(errno));
+			if (linked_loader) {
+				unlink("/usr/lib/ldqnx.so.2");
+			};
+			exit(-1);
+		};                        
+	};
+
+	/* Run the program, collect the result */
+	result = spawnv(P_WAIT,cmd,argv);
+	if (result == -1) {
+		result = -errno;
+	} else {
+		result = WEXITSTATUS(result);
+	};
+
+	/* Clean up */
+	if (started_pipe_server) { 
+		kill(started_pipe_server, SIGTERM);
+	};
+	if (linked_loader) {
+		unlink("/usr/lib/ldqnx.so.2");
+	};
+
+	if (result < 0) {
+		fprintf(stderr, _("call to spawnv failed (%s)\n"), strerror(-result));
+		exit(1);
+	} else {
+		exit(result);
+	};
+}
+#endif
+
 int _alpm_makepath(const char *path)
 {
 	return _alpm_makepath_mode(path, 0755);
@@ -557,10 +619,16 @@ int _alpm_run_chroot(alpm_handle_t *handle, const char *cmd, char *const argv[])
 			exit(1);
 		}
 		umask(0022);
+
+#ifdef __QNX__
+		/* never returns */
+		qnx_execv(cmd, argv); 
+#else		
 		execv(cmd, argv);
 		/* execv only returns if there was an error */
 		fprintf(stderr, _("call to execv failed (%s)\n"), strerror(errno));
 		exit(1);
+#endif		
 	} else {
 		/* this code runs for the parent only (wait on the child) */
 		int status;
diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c
index fce0131..a419416 100644
--- a/src/pacman/pacman.c
+++ b/src/pacman/pacman.c
@@ -1058,7 +1058,11 @@ int main(int argc, char *argv[])
 	/* Set up the structure to specify the new action. */
 	new_action.sa_handler = handler;
 	sigemptyset(&new_action.sa_mask);
+#ifdef __QNX__	
+	new_action.sa_flags = 0;
+#else
 	new_action.sa_flags = SA_RESTART;
+#endif	
 
 	/* assign our handler to any signals we care about */
 	for(i = 0; i < sizeof(signals) / sizeof(signals[0]); i++) {
-- 
2.3.0


More information about the pacman-dev mailing list