aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2025-08-19 15:31:17 +0000
committerLaurent Bercot <ska@appnovation.com>2025-08-19 15:31:17 +0000
commit982dbebfa6703c2ea5c3dd65dfaf46657fac8aa8 (patch)
treef5e14205c9de088e850580f689a55983c80c01ef /src
parent4e30b6899578bae9343bacf8840a80bf1ada0f2a (diff)
downloadskalibs-982dbebfa6703c2ea5c3dd65dfaf46657fac8aa8.tar.gz
Add qsortr, env_dump4
Signed-off-by: Laurent Bercot <ska@appnovation.com>
Diffstat (limited to 'src')
-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
8 files changed, 151 insertions, 49 deletions
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 ;
+}