[pacman-dev] Patches for QNX support
This patch set adds support for the QNX RTOS. The first four patches are essentially workarounds for QNX's libc; the last patch implements the QNX-specific sections in libalpm.
This small refactor reduces the number of replications of the local imeplementation of strndup. Signed-off-by: Will Miles <wmiles@sgl.com> --- src/util/Makefile.am | 4 ++-- src/util/pacsort.c | 23 +---------------------- src/util/pactree.c | 24 ++---------------------- src/util/util-common.c | 1 + src/util/util-common.h | 1 + 5 files changed, 7 insertions(+), 46 deletions(-) create mode 120000 src/util/util-common.c create mode 120000 src/util/util-common.h diff --git a/src/util/Makefile.am b/src/util/Makefile.am index 25c025b..936d7ff 100644 --- a/src/util/Makefile.am +++ b/src/util/Makefile.am @@ -20,10 +20,10 @@ AM_CFLAGS = -pedantic -D_GNU_SOURCE $(WARNING_CFLAGS) cleanupdelta_SOURCES = cleanupdelta.c cleanupdelta_LDADD = $(top_builddir)/lib/libalpm/.libs/libalpm.la -pacsort_SOURCES = pacsort.c +pacsort_SOURCES = pacsort.c util-common.c pacsort_LDADD = $(top_builddir)/lib/libalpm/.libs/libalpm.la -pactree_SOURCES = pactree.c +pactree_SOURCES = pactree.c util-common.c pactree_LDADD = $(top_builddir)/lib/libalpm/.libs/libalpm.la testpkg_SOURCES = testpkg.c diff --git a/src/util/pacsort.c b/src/util/pacsort.c index 02b9084..7081f5a 100644 --- a/src/util/pacsort.c +++ b/src/util/pacsort.c @@ -25,6 +25,7 @@ #include <string.h> #include <alpm.h> +#include "util-common.h" #define DELIM ' ' @@ -69,28 +70,6 @@ static struct options_t { char delim; } opts; -#ifndef HAVE_STRNDUP -/* A quick and dirty implementation derived from glibc */ -static size_t strnlen(const char *s, size_t max) -{ - register const char *p; - for(p = s; *p && max--; ++p); - return (p - s); -} - -char *strndup(const char *s, size_t n) -{ - size_t len = strnlen(s, n); - char *new = (char *) malloc(len + 1); - - if(new == NULL) - return NULL; - - new[len] = '\0'; - return (char *)memcpy(new, s, len); -} -#endif - static struct buffer_t *buffer_new(size_t initial_size) { struct buffer_t *buf; diff --git a/src/util/pactree.c b/src/util/pactree.c index 67f456f..11ad7ca 100644 --- a/src/util/pactree.c +++ b/src/util/pactree.c @@ -29,6 +29,8 @@ #include <langinfo.h> #endif +#include "util-common.h" + #define LINE_MAX 512 typedef struct tdepth { @@ -121,28 +123,6 @@ int searchsyncs = 0; const char *dbpath = DBPATH; const char *configfile = CONFFILE; -#ifndef HAVE_STRNDUP -/* A quick and dirty implementation derived from glibc */ -static size_t strnlen(const char *s, size_t max) -{ - register const char *p; - for(p = s; *p && max--; ++p); - return (p - s); -} - -char *strndup(const char *s, size_t n) -{ - size_t len = strnlen(s, n); - char *new = (char *) malloc(len + 1); - - if(new == NULL) - return NULL; - - new[len] = '\0'; - return (char *)memcpy(new, s, len); -} -#endif - static size_t strtrim(char *str) { char *end, *pch = str; diff --git a/src/util/util-common.c b/src/util/util-common.c new file mode 120000 index 0000000..a2f6c50 --- /dev/null +++ b/src/util/util-common.c @@ -0,0 +1 @@ +../common/util-common.c \ No newline at end of file diff --git a/src/util/util-common.h b/src/util/util-common.h new file mode 120000 index 0000000..3f0b982 --- /dev/null +++ b/src/util/util-common.h @@ -0,0 +1 @@ +../common/util-common.h \ No newline at end of file -- 2.3.0
On 27/02/15 08:04, Will Miles wrote:
This small refactor reduces the number of replications of the local imeplementation of strndup.
Typo ^ Fixed and pulled to my patchqueue.
Signed-off-by: Will Miles <wmiles@sgl.com> --- src/util/Makefile.am | 4 ++-- src/util/pacsort.c | 23 +---------------------- src/util/pactree.c | 24 ++---------------------- src/util/util-common.c | 1 + src/util/util-common.h | 1 + 5 files changed, 7 insertions(+), 46 deletions(-) create mode 120000 src/util/util-common.c create mode 120000 src/util/util-common.h
diff --git a/src/util/Makefile.am b/src/util/Makefile.am index 25c025b..936d7ff 100644 --- a/src/util/Makefile.am +++ b/src/util/Makefile.am @@ -20,10 +20,10 @@ AM_CFLAGS = -pedantic -D_GNU_SOURCE $(WARNING_CFLAGS) cleanupdelta_SOURCES = cleanupdelta.c cleanupdelta_LDADD = $(top_builddir)/lib/libalpm/.libs/libalpm.la
-pacsort_SOURCES = pacsort.c +pacsort_SOURCES = pacsort.c util-common.c pacsort_LDADD = $(top_builddir)/lib/libalpm/.libs/libalpm.la
-pactree_SOURCES = pactree.c +pactree_SOURCES = pactree.c util-common.c pactree_LDADD = $(top_builddir)/lib/libalpm/.libs/libalpm.la
testpkg_SOURCES = testpkg.c diff --git a/src/util/pacsort.c b/src/util/pacsort.c index 02b9084..7081f5a 100644 --- a/src/util/pacsort.c +++ b/src/util/pacsort.c @@ -25,6 +25,7 @@ #include <string.h>
#include <alpm.h> +#include "util-common.h"
#define DELIM ' '
@@ -69,28 +70,6 @@ static struct options_t { char delim; } opts;
-#ifndef HAVE_STRNDUP -/* A quick and dirty implementation derived from glibc */ -static size_t strnlen(const char *s, size_t max) -{ - register const char *p; - for(p = s; *p && max--; ++p); - return (p - s); -} - -char *strndup(const char *s, size_t n) -{ - size_t len = strnlen(s, n); - char *new = (char *) malloc(len + 1); - - if(new == NULL) - return NULL; - - new[len] = '\0'; - return (char *)memcpy(new, s, len); -} -#endif - static struct buffer_t *buffer_new(size_t initial_size) { struct buffer_t *buf; diff --git a/src/util/pactree.c b/src/util/pactree.c index 67f456f..11ad7ca 100644 --- a/src/util/pactree.c +++ b/src/util/pactree.c @@ -29,6 +29,8 @@ #include <langinfo.h> #endif
+#include "util-common.h" + #define LINE_MAX 512
typedef struct tdepth { @@ -121,28 +123,6 @@ int searchsyncs = 0; const char *dbpath = DBPATH; const char *configfile = CONFFILE;
-#ifndef HAVE_STRNDUP -/* A quick and dirty implementation derived from glibc */ -static size_t strnlen(const char *s, size_t max) -{ - register const char *p; - for(p = s; *p && max--; ++p); - return (p - s); -} - -char *strndup(const char *s, size_t n) -{ - size_t len = strnlen(s, n); - char *new = (char *) malloc(len + 1); - - if(new == NULL) - return NULL; - - new[len] = '\0'; - return (char *)memcpy(new, s, len); -} -#endif - static size_t strtrim(char *str) { char *end, *pch = str; diff --git a/src/util/util-common.c b/src/util/util-common.c new file mode 120000 index 0000000..a2f6c50 --- /dev/null +++ b/src/util/util-common.c @@ -0,0 +1 @@ +../common/util-common.c \ No newline at end of file diff --git a/src/util/util-common.h b/src/util/util-common.h new file mode 120000 index 0000000..3f0b982 --- /dev/null +++ b/src/util/util-common.h @@ -0,0 +1 @@ +../common/util-common.h \ No newline at end of file
Add a configure test for a system library supplied strnlen, and disable the embedded version in common if one is found. Signed-off-by: Will Miles <wmiles@sgl.com> --- configure.ac | 4 ++-- src/common/util-common.c | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 735fdc3..359d61b 100644 --- a/configure.ac +++ b/configure.ac @@ -304,8 +304,8 @@ AC_FUNC_MKTIME AC_FUNC_STRCOLL AC_CHECK_FUNCS([dup2 getcwd getmntinfo gettimeofday memmove memset \ mkdir realpath regcomp rmdir setenv setlocale strcasecmp \ - strchr strcspn strdup strerror strndup strrchr strsep strstr \ - strtol swprintf tcflush wcwidth uname]) + strchr strcspn strdup strerror strndup strnlen strrchr \ + strsep strstr strtol swprintf tcflush wcwidth uname]) AC_CHECK_MEMBERS([struct stat.st_blksize],,,[[#include <sys/stat.h>]]) # For the diskspace code diff --git a/src/common/util-common.c b/src/common/util-common.c index f5b00f1..e834168 100644 --- a/src/common/util-common.c +++ b/src/common/util-common.c @@ -127,7 +127,7 @@ char *safe_fgets(char *s, int size, FILE *stream) return ret; } -#ifndef HAVE_STRNDUP +#ifndef HAVE_STRNLEN /* A quick and dirty implementation derived from glibc */ /** Determines the length of a fixed-size string. * @param s string to be measured @@ -140,7 +140,9 @@ static size_t strnlen(const char *s, size_t max) for(p = s; *p && max--; ++p); return (p - s); } +#endif +#ifndef HAVE_STRNDUP /** Copies a string. * Returned string needs to be freed * @param s string to be copied -- 2.3.0
On 27/02/15 08:04, Will Miles wrote:
Add a configure test for a system library supplied strnlen, and disable the embedded version in common if one is found.
Signed-off-by: Will Miles <wmiles@sgl.com>
Ack
The specific implementation has been borrowed from glibc-2.21. Signed-off-by: Will Miles <wmiles@sgl.com> --- src/common/util-common.c | 142 +++++++++++++++++++++++++++++++++++++++++++++++ src/common/util-common.h | 6 ++ 2 files changed, 148 insertions(+) diff --git a/src/common/util-common.c b/src/common/util-common.c index e834168..e977550 100644 --- a/src/common/util-common.c +++ b/src/common/util-common.c @@ -163,4 +163,146 @@ char *strndup(const char *s, size_t n) } #endif + +#ifndef HAVE_WCWIDTH +/* Implementation derived from glibc. */ + +struct interval { + unsigned short first; + unsigned short last; +}; + +/* auxiliary function for binary search in interval table */ +static int bisearch(wchar_t ucs, const struct interval *table, int max) { + int min = 0; + int mid; + + if (ucs < table[0].first || ucs > table[max].last) + return 0; + while (max >= min) { + mid = (min + max) / 2; + if (ucs > table[mid].last) + min = mid + 1; + else if (ucs < table[mid].first) + max = mid - 1; + else + return 1; + } + + return 0; +} + + +/* The following functions define the column width of an ISO 10646 + * character as follows: + * + * - The null character (U+0000) has a column width of 0. + * + * - Other C0/C1 control characters and DEL will lead to a return + * value of -1. + * + * - Non-spacing and enclosing combining characters (general + * category code Mn or Me in the Unicode database) have a + * column width of 0. + * + * - Other format characters (general category code Cf in the Unicode + * database) and ZERO WIDTH SPACE (U+200B) have a column width of 0. + * + * - Hangul Jamo medial vowels and final consonants (U+1160-U+11FF) + * have a column width of 0. + * + * - Spacing characters in the East Asian Wide (W) or East Asian + * FullWidth (F) category as defined in Unicode Technical + * Report #11 have a column width of 2. + * + * - All remaining characters (including all printable + * ISO 8859-1 and WGL4 characters, Unicode control characters, + * etc.) have a column width of 1. + * + * This implementation assumes that wchar_t characters are encoded + * in ISO 10646. + */ + +int wcwidth(wchar_t ucs) +{ + /* sorted list of non-overlapping intervals of non-spacing characters */ + static const struct interval combining[] = { + { 0x0300, 0x034E }, { 0x0360, 0x0362 }, { 0x0483, 0x0486 }, + { 0x0488, 0x0489 }, { 0x0591, 0x05A1 }, { 0x05A3, 0x05B9 }, + { 0x05BB, 0x05BD }, { 0x05BF, 0x05BF }, { 0x05C1, 0x05C2 }, + { 0x05C4, 0x05C4 }, { 0x064B, 0x0655 }, { 0x0670, 0x0670 }, + { 0x06D6, 0x06E4 }, { 0x06E7, 0x06E8 }, { 0x06EA, 0x06ED }, + { 0x070F, 0x070F }, { 0x0711, 0x0711 }, { 0x0730, 0x074A }, + { 0x07A6, 0x07B0 }, { 0x0901, 0x0902 }, { 0x093C, 0x093C }, + { 0x0941, 0x0948 }, { 0x094D, 0x094D }, { 0x0951, 0x0954 }, + { 0x0962, 0x0963 }, { 0x0981, 0x0981 }, { 0x09BC, 0x09BC }, + { 0x09C1, 0x09C4 }, { 0x09CD, 0x09CD }, { 0x09E2, 0x09E3 }, + { 0x0A02, 0x0A02 }, { 0x0A3C, 0x0A3C }, { 0x0A41, 0x0A42 }, + { 0x0A47, 0x0A48 }, { 0x0A4B, 0x0A4D }, { 0x0A70, 0x0A71 }, + { 0x0A81, 0x0A82 }, { 0x0ABC, 0x0ABC }, { 0x0AC1, 0x0AC5 }, + { 0x0AC7, 0x0AC8 }, { 0x0ACD, 0x0ACD }, { 0x0B01, 0x0B01 }, + { 0x0B3C, 0x0B3C }, { 0x0B3F, 0x0B3F }, { 0x0B41, 0x0B43 }, + { 0x0B4D, 0x0B4D }, { 0x0B56, 0x0B56 }, { 0x0B82, 0x0B82 }, + { 0x0BC0, 0x0BC0 }, { 0x0BCD, 0x0BCD }, { 0x0C3E, 0x0C40 }, + { 0x0C46, 0x0C48 }, { 0x0C4A, 0x0C4D }, { 0x0C55, 0x0C56 }, + { 0x0CBF, 0x0CBF }, { 0x0CC6, 0x0CC6 }, { 0x0CCC, 0x0CCD }, + { 0x0D41, 0x0D43 }, { 0x0D4D, 0x0D4D }, { 0x0DCA, 0x0DCA }, + { 0x0DD2, 0x0DD4 }, { 0x0DD6, 0x0DD6 }, { 0x0E31, 0x0E31 }, + { 0x0E34, 0x0E3A }, { 0x0E47, 0x0E4E }, { 0x0EB1, 0x0EB1 }, + { 0x0EB4, 0x0EB9 }, { 0x0EBB, 0x0EBC }, { 0x0EC8, 0x0ECD }, + { 0x0F18, 0x0F19 }, { 0x0F35, 0x0F35 }, { 0x0F37, 0x0F37 }, + { 0x0F39, 0x0F39 }, { 0x0F71, 0x0F7E }, { 0x0F80, 0x0F84 }, + { 0x0F86, 0x0F87 }, { 0x0F90, 0x0F97 }, { 0x0F99, 0x0FBC }, + { 0x0FC6, 0x0FC6 }, { 0x102D, 0x1030 }, { 0x1032, 0x1032 }, + { 0x1036, 0x1037 }, { 0x1039, 0x1039 }, { 0x1058, 0x1059 }, + { 0x1160, 0x11FF }, { 0x17B7, 0x17BD }, { 0x17C6, 0x17C6 }, + { 0x17C9, 0x17D3 }, { 0x180B, 0x180E }, { 0x18A9, 0x18A9 }, + { 0x200B, 0x200F }, { 0x202A, 0x202E }, { 0x206A, 0x206F }, + { 0x20D0, 0x20E3 }, { 0x302A, 0x302F }, { 0x3099, 0x309A }, + { 0xFB1E, 0xFB1E }, { 0xFE20, 0xFE23 }, { 0xFEFF, 0xFEFF }, + { 0xFFF9, 0xFFFB } + }; + + /* test for 8-bit control characters */ + if (ucs == 0) + return 0; + if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0)) + return -1; + + /* binary search in table of non-spacing characters */ + if (bisearch(ucs, combining, + sizeof(combining) / sizeof(struct interval) - 1)) + return 0; + + /* if we arrive here, ucs is not a combining or C0/C1 control character */ + + return 1 + + (ucs >= 0x1100 && + (ucs <= 0x115f || /* Hangul Jamo init. consonants */ + (ucs >= 0x2e80 && ucs <= 0xa4cf && (ucs & ~0x0011) != 0x300a && + ucs != 0x303f) || /* CJK ... Yi */ + (ucs >= 0xac00 && ucs <= 0xd7a3) || /* Hangul Syllables */ + (ucs >= 0xf900 && ucs <= 0xfaff) || /* CJK Compatibility Ideographs */ + (ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */ + (ucs >= 0xff00 && ucs <= 0xff5f) || /* Fullwidth Forms */ + (ucs >= 0xffe0 && ucs <= 0xffe6) || + (ucs >= 0x20000 && ucs <= 0x2ffff))); +} + + +int wcswidth(const wchar_t *pwcs, size_t n) +{ + int w, width = 0; + + for (;*pwcs && n-- > 0; pwcs++) + if ((w = wcwidth(*pwcs)) < 0) + return -1; + else + width += w; + + return width; +} +#endif /* HAVE_WCWIDTH */ + + /* vim: set noet: */ diff --git a/src/common/util-common.h b/src/common/util-common.h index a2093be..117486f 100644 --- a/src/common/util-common.h +++ b/src/common/util-common.h @@ -34,6 +34,12 @@ char *safe_fgets(char *s, int size, FILE *stream); char *strndup(const char *s, size_t n); #endif +#ifndef HAVE_WCWIDTH +int wcwidth(wchar_t ucs); +int wcswidth(const wchar_t *pwcs, size_t n); +#endif + + #endif /* _PM_UTIL_COMMON_H */ /* vim: set noet: */ -- 2.3.0
Signed-off-by: Will Miles <wmiles@sgl.com> --- configure.ac | 2 +- src/common/util-common.c | 27 +++++++++++++++++++++++++++ src/common/util-common.h | 7 +++++++ 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 359d61b..da1953e 100644 --- a/configure.ac +++ b/configure.ac @@ -302,7 +302,7 @@ AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK AC_FUNC_MALLOC AC_FUNC_MKTIME AC_FUNC_STRCOLL -AC_CHECK_FUNCS([dup2 getcwd getmntinfo gettimeofday memmove memset \ +AC_CHECK_FUNCS([asprintf dup2 getcwd getmntinfo gettimeofday memmove memset \ mkdir realpath regcomp rmdir setenv setlocale strcasecmp \ strchr strcspn strdup strerror strndup strnlen strrchr \ strsep strstr strtol swprintf tcflush wcwidth uname]) diff --git a/src/common/util-common.c b/src/common/util-common.c index e977550..d7ef08b 100644 --- a/src/common/util-common.c +++ b/src/common/util-common.c @@ -305,4 +305,31 @@ int wcswidth(const wchar_t *pwcs, size_t n) #endif /* HAVE_WCWIDTH */ +#ifndef HAVE_ASPRINTF +int asprintf(char **strp, const char *fmt, ...) +{ + int ret = 0; + va_list args; + + /* print the message using va_arg list */ + va_start(args, fmt); + ret = vasprintf(strp, fmt, args); + va_end(args); + return ret; +} + +int vasprintf(char **strp, const char *fmt, va_list ap) +{ + /* measure the string */ + int len = vsnprintf(NULL,0,fmt,ap); + /* try allocating some memory */ + if ((len < 0) || ((*strp = malloc(++len)) == NULL)) return -1; + /* print the string */ + len = vsnprintf(*strp,len,fmt,ap); + /* handle failure */ + if (len < 0) free(*strp); + return len; +} +#endif /* HAVE_ASPRINTF */ + /* vim: set noet: */ diff --git a/src/common/util-common.h b/src/common/util-common.h index 117486f..ca1bc5d 100644 --- a/src/common/util-common.h +++ b/src/common/util-common.h @@ -22,6 +22,9 @@ #include <stdio.h> #include <sys/stat.h> /* struct stat */ +#ifndef HAVE_ASPRINTF +#include <stdarg.h> +#endif const char *mbasename(const char *path); char *mdirname(const char *path); @@ -39,6 +42,10 @@ int wcwidth(wchar_t ucs); int wcswidth(const wchar_t *pwcs, size_t n); #endif +#ifndef HAVE_ASPRINTF +int asprintf(char **strp, const char *fmt, ...) __attribute__((format(printf,2,3))); +int vasprintf(char **strp, const char *fmt, va_list ap) __attribute__((format(printf,3,0))); +#endif #endif /* _PM_UTIL_COMMON_H */ -- 2.3.0
Signed-off-by: Will Miles <wmiles@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
participants (2)
-
Allan McRae
-
Will Miles