aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xconfigure2
-rw-r--r--package/deps.mak4
-rw-r--r--src/include/skalibs/env.h1
-rw-r--r--src/include/skalibs/posixplz.h3
-rw-r--r--src/libenvexec/env_dump.c48
-rw-r--r--src/libenvexec/env_dump4.c55
-rw-r--r--src/libposixplz/qsortr.c48
-rw-r--r--src/libunixonacid/emulate_at.c7
-rw-r--r--src/sysdeps/tryqsortr_freebsd.c19
-rw-r--r--src/sysdeps/tryqsortr_posix.c19
10 files changed, 156 insertions, 50 deletions
diff --git a/configure b/configure
index eb804ec..53b5194 100755
--- a/configure
+++ b/configure
@@ -682,6 +682,8 @@ choose cl linkat 'linkat()'
choose cl memmem 'memmem()'
choose cl pipe2 'pipe2()'
choose cl ppoll 'ppoll()'
+choose cl qsortr_posix 'POSIX qsort_r()'
+choose cl qsortr_freebsd 'old FreeBSD qsort_r()'
choose cl revoke 'revoke()'
choose cl sendfile 'sendfile()'
choose cl setgroups 'setgroups()'
diff --git a/package/deps.mak b/package/deps.mak
index b4fe193..420fb67 100644
--- a/package/deps.mak
+++ b/package/deps.mak
@@ -126,7 +126,8 @@ src/libenvexec/child_spawn2.o src/libenvexec/child_spawn2.lo: src/libenvexec/chi
src/libenvexec/child_spawn3.o src/libenvexec/child_spawn3.lo: src/libenvexec/child_spawn3.c src/include/skalibs/cspawn.h src/include/skalibs/djbunix.h src/include/skalibs/env.h src/include/skalibs/types.h
src/libenvexec/cspawn.o src/libenvexec/cspawn.lo: src/libenvexec/cspawn.c src/include/skalibs/allreadwrite.h src/include/skalibs/config.h src/include/skalibs/cspawn.h src/include/skalibs/djbunix.h src/include/skalibs/exec.h src/include/skalibs/nonposix.h src/include/skalibs/posixplz.h src/include/skalibs/selfpipe.h src/include/skalibs/sig.h src/include/skalibs/sysdeps.h
src/libenvexec/env_addmodif.o src/libenvexec/env_addmodif.lo: src/libenvexec/env_addmodif.c src/include/skalibs/env.h src/include/skalibs/stralloc.h
-src/libenvexec/env_dump.o src/libenvexec/env_dump.lo: src/libenvexec/env_dump.c src/include/skalibs/bytestr.h src/include/skalibs/djbunix.h src/include/skalibs/env.h src/include/skalibs/nonposix.h src/include/skalibs/unix-transactional.h
+src/libenvexec/env_dump.o src/libenvexec/env_dump.lo: src/libenvexec/env_dump.c src/include/skalibs/env.h
+src/libenvexec/env_dump4.o src/libenvexec/env_dump4.lo: src/libenvexec/env_dump4.c src/include/skalibs/bytestr.h src/include/skalibs/djbunix.h src/include/skalibs/env.h src/include/skalibs/nonposix.h src/include/skalibs/unix-transactional.h
src/libenvexec/env_get.o src/libenvexec/env_get.lo: src/libenvexec/env_get.c src/include/skalibs/posixplz.h
src/libenvexec/env_get2.o src/libenvexec/env_get2.lo: src/libenvexec/env_get2.c src/include/skalibs/bytestr.h src/include/skalibs/env.h
src/libenvexec/env_len.o src/libenvexec/env_len.lo: src/libenvexec/env_len.c src/include/skalibs/env.h
@@ -190,6 +191,7 @@ src/libposixplz/mkptemp.o src/libposixplz/mkptemp.lo: src/libposixplz/mkptemp.c
src/libposixplz/mkptemp2.o src/libposixplz/mkptemp2.lo: src/libposixplz/mkptemp2.c src/include/skalibs/posixplz.h
src/libposixplz/mkptemp3.o src/libposixplz/mkptemp3.lo: src/libposixplz/mkptemp3.c src/include/skalibs/djbunix.h src/include/skalibs/fcntl.h src/include/skalibs/posixplz.h
src/libposixplz/munmap_void.o src/libposixplz/munmap_void.lo: src/libposixplz/munmap_void.c src/include/skalibs/posixplz.h
+src/libposixplz/qsortr.o src/libposixplz/qsortr.lo: src/libposixplz/qsortr.c src/include/skalibs/functypes.h src/include/skalibs/posixplz.h src/include/skalibs/sysdeps.h
src/libposixplz/setgroups.o src/libposixplz/setgroups.lo: src/libposixplz/setgroups.c src/include/skalibs/nonposix.h src/include/skalibs/posixishard.h src/include/skalibs/setgroups.h src/include/skalibs/sysdeps.h
src/libposixplz/strcasestr.o src/libposixplz/strcasestr.lo: src/libposixplz/strcasestr.c src/include/skalibs/bytestr.h src/include/skalibs/sysdeps.h
src/libposixplz/strnlen.o src/libposixplz/strnlen.lo: src/libposixplz/strnlen.c src/include/skalibs/bytestr.h src/include/skalibs/posixishard.h src/include/skalibs/sysdeps.h
diff --git a/src/include/skalibs/env.h b/src/include/skalibs/env.h
index 4d6dcc9..c09dd7c 100644
--- a/src/include/skalibs/env.h
+++ b/src/include/skalibs/env.h
@@ -32,5 +32,6 @@ extern int envdir_internal (char const *, stralloc *, unsigned int, char) ;
#define envdir_verbatim_chomp(path, sa) envdir_internal(path, (sa), SKALIBS_ENVDIR_VERBATIM, '\n')
#define envdir_verbatim(path, sa) envdir_internal(path, (sa), SKALIBS_ENVDIR_VERBATIM|SKALIBS_ENVDIR_NOCHOMP, '\n')
extern int env_dump (char const *, mode_t, char const *const *) ;
+extern int env_dump4 (char const *, mode_t, char const *const *, int) ;
#endif
diff --git a/src/include/skalibs/posixplz.h b/src/include/skalibs/posixplz.h
index 3c6c520..e413739 100644
--- a/src/include/skalibs/posixplz.h
+++ b/src/include/skalibs/posixplz.h
@@ -4,7 +4,7 @@
#define SKALIBS_POSIXPLZ_H
#include <sys/types.h>
-#include <sys/stat.h>
+#include <stdlib.h>
#include <regex.h>
#include <skalibs/gccattributes.h>
@@ -59,6 +59,7 @@ extern int mkbtemp (char *, mode_t, dev_t) ;
Wrappers around functions that should be specified better.
*/
+extern void qsortr (void *, size_t, size_t, cmp_func_ref, void *) ;
#define skalibs_regcomp(re, s, flags) regcomp(re, (s)[0] ? (s) : ".*", flags)
#endif
diff --git a/src/libenvexec/env_dump.c b/src/libenvexec/env_dump.c
index 10f5913..f76aa83 100644
--- a/src/libenvexec/env_dump.c
+++ b/src/libenvexec/env_dump.c
@@ -1,54 +1,8 @@
/* ISC license. */
-#include <skalibs/nonposix.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include <skalibs/bytestr.h>
#include <skalibs/env.h>
-#include <skalibs/djbunix.h>
-
- /* XXX: breaks layering, but really openat() should be supported everywhere */
-#include <skalibs/unix-transactional.h>
-
-#define SUFFIX ":envdump:XXXXXX"
int env_dump (char const *dir, mode_t mode, char const *const *envp)
{
- int fd ;
- size_t dirlen = strlen(dir) ;
- char tmpdir[dirlen + sizeof(SUFFIX)] ;
- memcpy(tmpdir, dir, dirlen) ;
- memcpy(tmpdir + dirlen, SUFFIX, sizeof(SUFFIX)) ;
- if (!mkdtemp(tmpdir)) return 0 ;
- fd = open_read(tmpdir) ;
- if (fd == -1) goto err ;
- for (; *envp ; envp++)
- {
- size_t len = str_chr(*envp, '=') ;
- size_t vallen = strlen(*envp + len + 1) ;
- char fn[len + 1] ;
- memcpy(fn, *envp, len) ;
- fn[len] = 0 ;
- len = openwritenclose_at(fd, fn, *envp + len + 1, vallen) ;
- if (len < vallen) goto cerr ;
- }
- fd_close(fd) ;
- if (chmod(tmpdir, mode) == -1) goto err ;
- if (rename(tmpdir, dir) == -1) goto err ;
- return 1 ;
-
- cerr:
- fd_close(fd) ;
- err:
- {
- int e = errno ;
- rm_rf(tmpdir) ;
- errno = e ;
- }
- return 0 ;
+ return env_dump4(dir, mode, envp, 1) ;
}
diff --git a/src/libenvexec/env_dump4.c b/src/libenvexec/env_dump4.c
new file mode 100644
index 0000000..b59c858
--- /dev/null
+++ b/src/libenvexec/env_dump4.c
@@ -0,0 +1,55 @@
+/* ISC license. */
+
+#include <skalibs/nonposix.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <skalibs/bytestr.h>
+#include <skalibs/env.h>
+#include <skalibs/djbunix.h>
+
+ /* XXX: breaks layering, but really openat() should be supported everywhere */
+#include <skalibs/unix-transactional.h>
+
+#define SUFFIX ":envdump:XXXXXX"
+
+int env_dump4 (char const *dir, mode_t mode, char const *const *envp, int nochomp)
+{
+ int fd ;
+ size_t dirlen = strlen(dir) ;
+ char tmpdir[dirlen + sizeof(SUFFIX)] ;
+ memcpy(tmpdir, dir, dirlen) ;
+ memcpy(tmpdir + dirlen, SUFFIX, sizeof(SUFFIX)) ;
+ if (!mkdtemp(tmpdir)) return 0 ;
+ fd = open_read(tmpdir) ;
+ if (fd == -1) goto err ;
+ for (; *envp ; envp++)
+ {
+ size_t len = str_chr(*envp, '=') ;
+ size_t vallen = strlen(*envp + len + 1) ;
+ char fn[len + 1 + !nochomp] ;
+ memcpy(fn, *envp, len) ;
+ if (nochomp) fn[len] = 0 ;
+ else { fn[len] = '\n' ; fn[len+1] = 0 ; }
+ len = openwritenclose_at(fd, fn, *envp + len + 1 + !nochomp, vallen) ;
+ if (len < vallen) goto cerr ;
+ }
+ fd_close(fd) ;
+ if (chmod(tmpdir, mode) == -1) goto err ;
+ if (rename(tmpdir, dir) == -1) goto err ;
+ return 1 ;
+
+ cerr:
+ fd_close(fd) ;
+ err:
+ {
+ int e = errno ;
+ rm_rf(tmpdir) ;
+ errno = e ;
+ }
+ return 0 ;
+}
diff --git a/src/libposixplz/qsortr.c b/src/libposixplz/qsortr.c
new file mode 100644
index 0000000..5fa7dd1
--- /dev/null
+++ b/src/libposixplz/qsortr.c
@@ -0,0 +1,48 @@
+/* ISC license. */
+
+#include <skalibs/sysdeps.h>
+
+#include <stdlib.h>
+
+#ifdef SKALIBS_HASQSORTR_POSIX
+
+void qsortr (void *base, size_t n, size_t width, cmp_func_ref f, void *data)
+{
+ qsort_r(base, n, width, f, data) ;
+}
+
+#else
+#ifdef SKALIBS_HASQSORTR_FREEBSD
+
+void qsortr (void *base, size_t n, size_t width, cmp_func_ref f, void *data)
+{
+ qsort_r(base, n, width, data, f) ;
+}
+
+#else
+
+#include <skalibs/functypes.h>
+#include <skalibs/posixplz.h>
+
+struct aux_s
+{
+ cmp_func_ref f ;
+ void *data ;
+} ;
+
+static struct aux_s *qsortr_aux_here ;
+
+static int cmp (void const *a, void const *b)
+{
+ return (*qsortr_aux_here->f)(a, b, qsortr_aux_here->data) ;
+}
+
+void qsortr (void *base, size_t n, size_t width, cmp_func_ref f, void *data)
+{
+ struct aux_s aux = { .f = f, .data = data } ;
+ qsortr_aux_here = &aux ;
+ qsort(base, n, width, &cmp) ;
+}
+
+#endif
+#endif
diff --git a/src/libunixonacid/emulate_at.c b/src/libunixonacid/emulate_at.c
index dc72c70..aed1081 100644
--- a/src/libunixonacid/emulate_at.c
+++ b/src/libunixonacid/emulate_at.c
@@ -7,6 +7,7 @@
#include <skalibs/bsdsnowflake.h>
#include <errno.h>
+#include <fcntl.h>
#include <skalibs/functypes.h>
#include <skalibs/djbunix.h>
@@ -16,7 +17,11 @@
int emulate_at (int dirfd, init_func_ref f, deinit_func_ref g, void *p)
{
int r ;
- int fdhere = open_read(".", O_DIRECTORY) ;
+#ifdef SKALIBS_HASODIRECTORY
+ int fdhere = open2(".", O_RDONLY | O_DIRECTORY) ;
+#else
+ int fdhere = open_readb(".") ;
+#endif
if (fdhere < 0) return -1 ;
if (fd_chdir(dirfd) < 0) goto errclose ;
r = (*f)(p) ;
diff --git a/src/sysdeps/tryqsortr_freebsd.c b/src/sysdeps/tryqsortr_freebsd.c
new file mode 100644
index 0000000..6bf090a
--- /dev/null
+++ b/src/sysdeps/tryqsortr_freebsd.c
@@ -0,0 +1,19 @@
+/* ISC license. */
+
+#include <stdlib.h>
+
+static int f (void const *a, void const *b, void *c)
+{
+ int aa = *(int *)a ;
+ int bb = *(int *)b ;
+ (void)c ;
+ return aa < bb ? -1 : aa > bb ;
+}
+
+int main (void)
+{
+ char *x = "blah" ;
+ int x[2] = { 2, 1 } ;
+ qsort_r(x, 2, sizeof(int), x, &f) ;
+ return 0 ;
+}
diff --git a/src/sysdeps/tryqsortr_posix.c b/src/sysdeps/tryqsortr_posix.c
new file mode 100644
index 0000000..63c1d60
--- /dev/null
+++ b/src/sysdeps/tryqsortr_posix.c
@@ -0,0 +1,19 @@
+/* ISC license. */
+
+#include <stdlib.h>
+
+static int f (void const *a, void const *b, void *c)
+{
+ int aa = *(int *)a ;
+ int bb = *(int *)b ;
+ (void)c ;
+ return aa < bb ? -1 : aa > bb ;
+}
+
+int main (void)
+{
+ char *x = "blah" ;
+ int x[2] = { 2, 1 } ;
+ qsort_r(x, 2, sizeof(int), &f, x) ;
+ return 0 ;
+}