summaryrefslogtreecommitdiff
path: root/system/musl
diff options
context:
space:
mode:
Diffstat (limited to 'system/musl')
-rw-r--r--system/musl/APKBUILD4
-rw-r--r--system/musl/amalgamation.patch329
-rw-r--r--system/musl/strftime-add-l-support.patch25
3 files changed, 221 insertions, 137 deletions
diff --git a/system/musl/APKBUILD b/system/musl/APKBUILD
index 86baab9f1..1cd0a2a6e 100644
--- a/system/musl/APKBUILD
+++ b/system/musl/APKBUILD
@@ -26,7 +26,6 @@ source="https://distfiles.adelielinux.org/source/$pkgname-$pkgver.tar.xz
3001-make-real-lastlog-h.patch
handle-aux-at_base.patch
fgetspent_r.patch
- strftime-add-l-support.patch
ldconfig
getent.c
@@ -118,11 +117,10 @@ utils() {
}
sha512sums="7026b67590a5dc0eda96777476a902e3d7121813d9ff9d9dabec3774365b9d43ce06314c434224fc8eef2b858107e42c10f220b6009ce4b919d8d9996cfcb839 musl-1.2.0_alpha1.tar.xz
-ef532aebeaa89b3274f7f75f1adaa4d1eea60f4e2822a6711c748768cc3a65a77ebd218d7a8ab41157684f7855dd4c5c2cdea7461b7569264d3517deba0ef9b2 amalgamation.patch
+f16a76c1f7dd70cda8013507c2feee905a2bb8d2aa4e6a88b7dbe3b8b587be747821079a052b1fd24691162e7606912b5e0c2c2b0402db51bb768ea28a9c5c9f amalgamation.patch
88ae443dbb8e0a4368235bdc3a1c5c7b718495afa75e06deb8e01becc76cb1f0d6964589e2204fc749c9c1b3190b8b9ac1ae2c0099cab8e2ce3ec877103d4332 3001-make-real-lastlog-h.patch
6a7ff16d95b5d1be77e0a0fbb245491817db192176496a57b22ab037637d97a185ea0b0d19da687da66c2a2f5578e4343d230f399d49fe377d8f008410974238 handle-aux-at_base.patch
ded41235148930f8cf781538f7d63ecb0c65ea4e8ce792565f3649ee2523592a76b2a166785f0b145fc79f5852fd1fb1729a7a09110b3b8f85cba3912e790807 fgetspent_r.patch
-7ed6c620a5ea5585c323936b1ff01eb7f01a1192240706a0d0470b661a7a03ea10ed17507c59678aaedce51b7a5ea839c2f528f19f12de02119bf4e47f7c3998 strftime-add-l-support.patch
cb71d29a87f334c75ecbc911becde7be825ab30d8f39fa6d64cb53812a7c9abaf91d9804c72540e5be3ddd3c84cfe7fd9632274309005cb8bcdf9a9b09b4b923 ldconfig
378d70e65bcc65bb4e1415354cecfa54b0c1146dfb24474b69e418cdbf7ad730472cd09f6f103e1c99ba6c324c9560bccdf287f5889bbc3ef0bdf0e08da47413 getent.c
9d42d66fb1facce2b85dad919be5be819ee290bd26ca2db00982b2f8e055a0196290a008711cbe2b18ec9eee8d2270e3b3a4692c5a1b807013baa5c2b70a2bbf iconv.c"
diff --git a/system/musl/amalgamation.patch b/system/musl/amalgamation.patch
index e53290e21..6f66a18cb 100644
--- a/system/musl/amalgamation.patch
+++ b/system/musl/amalgamation.patch
@@ -1,5 +1,5 @@
diff --git a/include/stdlib.h b/include/stdlib.h
-index 42ca8336..4bbaded0 100644
+index 194c2033..5734b1f0 100644
--- a/include/stdlib.h
+++ b/include/stdlib.h
@@ -39,14 +39,18 @@ void *malloc (size_t);
@@ -38,7 +38,7 @@ index 42ca8336..4bbaded0 100644
void *valloc (size_t);
void *memalign(size_t, size_t);
diff --git a/include/time.h b/include/time.h
-index 672b3fc3..c5946dd0 100644
+index 5494df18..2412fe22 100644
--- a/include/time.h
+++ b/include/time.h
@@ -58,11 +58,14 @@ struct tm *gmtime (const time_t *);
@@ -48,7 +48,7 @@ index 672b3fc3..c5946dd0 100644
-int timespec_get(struct timespec *, int);
-#define CLOCKS_PER_SEC 1000000L
-+#if __STDC_VERSION__ >= 201112L
++#if __STDC_VERSION__ >= 201112L || defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
+int timespec_get(struct timespec *, int);
#define TIME_UTC 1
@@ -58,11 +58,58 @@ index 672b3fc3..c5946dd0 100644
#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
|| defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+@@ -137,7 +140,10 @@ __REDIR(mktime, __mktime64);
+ __REDIR(gmtime, __gmtime64);
+ __REDIR(localtime, __localtime64);
+ __REDIR(ctime, __ctime64);
++# if __STDC_VERSION__ >= 201112L || defined(_BSD_SOURCE) \
++ || defined(_GNU_SOURCE)
+ __REDIR(timespec_get, __timespec_get_time64);
++# endif
+ #if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+ || defined(_BSD_SOURCE)
diff --git a/include/unistd.h b/include/unistd.h
-index 9485da7a..1bdd3292 100644
+index 7bcbff94..6fd67160 100644
--- a/include/unistd.h
+++ b/include/unistd.h
-@@ -274,6 +274,7 @@ int eaccess(const char *, int);
+@@ -33,16 +33,23 @@ extern "C" {
+ #include <bits/alltypes.h>
+
+ int pipe(int [2]);
+-int pipe2(int [2], int);
+ int close(int);
+-int posix_close(int, int);
+ int dup(int);
+ int dup2(int, int);
+-int dup3(int, int, int);
+ off_t lseek(int, off_t, int);
+ int fsync(int);
+ int fdatasync(int);
+
++#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) \
++ || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE+0 > 700) \
++ || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE+0 > 200809L)
++int pipe2(int [2], int);
++int dup3(int, int, int);
++int posix_close(int, int);
++
++#define POSIX_CLOSE_RESTART 0
++#endif
++
+ ssize_t read(int, void *, size_t);
+ ssize_t write(int, const void *, size_t);
+ ssize_t pread(int, void *, size_t, off_t);
+@@ -202,8 +209,6 @@ ssize_t copy_file_range(int, off_t *, int, off_t *, size_t, unsigned);
+ #define off64_t off_t
+ #endif
+
+-#define POSIX_CLOSE_RESTART 0
+-
+ #define _XOPEN_VERSION 700
+ #define _XOPEN_UNIX 1
+ #define _XOPEN_ENH_I18N 1
+@@ -276,6 +281,7 @@ ssize_t copy_file_range(int, off_t *, int, off_t *, size_t, unsigned);
#define _PC_ALLOC_SIZE_MIN 18
#define _PC_SYMLINK_MAX 19
#define _PC_2_SYMLINKS 20
@@ -70,7 +117,7 @@ index 9485da7a..1bdd3292 100644
#define _SC_ARG_MAX 0
#define _SC_CHILD_MAX 1
-@@ -417,6 +418,7 @@ int eaccess(const char *, int);
+@@ -419,6 +425,7 @@ ssize_t copy_file_range(int, off_t *, int, off_t *, size_t, unsigned);
#define _SC_XOPEN_STREAMS 246
#define _SC_THREAD_ROBUST_PRIO_INHERIT 247
#define _SC_THREAD_ROBUST_PRIO_PROTECT 248
@@ -78,7 +125,7 @@ index 9485da7a..1bdd3292 100644
#define _CS_PATH 0
#define _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS 1
-@@ -459,6 +461,8 @@ int eaccess(const char *, int);
+@@ -461,6 +468,8 @@ ssize_t copy_file_range(int, off_t *, int, off_t *, size_t, unsigned);
#define _CS_POSIX_V7_LPBIG_OFFBIG_LINTFLAGS 1147
#define _CS_V6_ENV 1148
#define _CS_V7_ENV 1149
@@ -103,18 +150,20 @@ index 02cb1aa2..8f870a69 100644
return 0;
}
diff --git a/src/conf/fpathconf.c b/src/conf/fpathconf.c
-index e6aca5cf..b6a9d63e 100644
+index e6aca5cf..83e47e87 100644
--- a/src/conf/fpathconf.c
+++ b/src/conf/fpathconf.c
-@@ -4,7 +4,7 @@
+@@ -4,8 +4,8 @@
long fpathconf(int fd, int name)
{
- static const short values[] = {
+- [_PC_LINK_MAX] = _POSIX_LINK_MAX,
+ static const long values[] = {
- [_PC_LINK_MAX] = _POSIX_LINK_MAX,
++ [_PC_LINK_MAX] = -1,
[_PC_MAX_CANON] = _POSIX_MAX_CANON,
[_PC_MAX_INPUT] = _POSIX_MAX_INPUT,
+ [_PC_NAME_MAX] = NAME_MAX,
@@ -25,7 +25,8 @@ long fpathconf(int fd, int name)
[_PC_REC_XFER_ALIGN] = 4096,
[_PC_ALLOC_SIZE_MIN] = 4096,
@@ -126,7 +175,7 @@ index e6aca5cf..b6a9d63e 100644
if (name >= sizeof(values)/sizeof(values[0])) {
errno = EINVAL;
diff --git a/src/conf/sysconf.c b/src/conf/sysconf.c
-index 45ef1c16..483e1635 100644
+index 3baaed32..04369596 100644
--- a/src/conf/sysconf.c
+++ b/src/conf/sysconf.c
@@ -165,6 +165,7 @@ long sysconf(int name)
@@ -138,10 +187,10 @@ index 45ef1c16..483e1635 100644
if (name >= sizeof(values)/sizeof(values[0]) || !values[name]) {
diff --git a/src/locale/setlocale.c b/src/locale/setlocale.c
-index 40bc7ece..4d51cdfe 100644
+index 2bc7b500..4a601eaf 100644
--- a/src/locale/setlocale.c
+++ b/src/locale/setlocale.c
-@@ -11,6 +11,8 @@ char *setlocale(int cat, const char *name)
+@@ -14,6 +14,8 @@ char *setlocale(int cat, const char *name)
if ((unsigned)cat > LC_ALL) return 0;
@@ -150,6 +199,24 @@ index 40bc7ece..4d51cdfe 100644
LOCK(lock);
/* For LC_ALL, setlocale is required to return a string which
+diff --git a/src/misc/forkpty.c b/src/misc/forkpty.c
+index caf13adb..43494b96 100644
+--- a/src/misc/forkpty.c
++++ b/src/misc/forkpty.c
+@@ -1,3 +1,4 @@
++#define _GNU_SOURCE
+ #include <pty.h>
+ #include <utmp.h>
+ #include <unistd.h>
+diff --git a/src/misc/wordexp.c b/src/misc/wordexp.c
+index db83a69f..be9cb6d5 100644
+--- a/src/misc/wordexp.c
++++ b/src/misc/wordexp.c
+@@ -1,3 +1,4 @@
++#define _GNU_SOURCE
+ #include <wordexp.h>
+ #include <unistd.h>
+ #include <stdio.h>
diff --git a/src/process/execlp.c b/src/process/execlp.c
index 5eed886e..f6da398b 100644
--- a/src/process/execlp.c
@@ -202,18 +269,18 @@ index 00000000..180bb2aa
+ return execv("/bin/sh", nargv);
+}
diff --git a/src/process/execvp.c b/src/process/execvp.c
-index 2dddeddb..fdd0ca48 100644
+index ef3b9dd5..5e6255f7 100644
--- a/src/process/execvp.c
+++ b/src/process/execvp.c
-@@ -6,6 +6,7 @@
- #include "libc.h"
+@@ -5,6 +5,7 @@
+ #include <limits.h>
extern char **__environ;
+extern int __execsh(const char *, char *const []);
int __execvpe(const char *file, char *const argv[], char *const envp[])
{
-@@ -56,7 +57,12 @@ int __execvpe(const char *file, char *const argv[], char *const envp[])
+@@ -54,7 +55,12 @@ int __execvpe(const char *file, char *const argv[], char *const envp[])
int execvp(const char *file, char *const argv[])
{
@@ -228,10 +295,10 @@ index 2dddeddb..fdd0ca48 100644
weak_alias(__execvpe, execvpe);
diff --git a/src/process/system.c b/src/process/system.c
-index 9135b815..aa01e13b 100644
+index 5af59b80..3f61d278 100644
--- a/src/process/system.c
+++ b/src/process/system.c
-@@ -19,7 +19,9 @@ int system(const char *cmd)
+@@ -18,7 +18,9 @@ int system(const char *cmd)
pthread_testcancel();
@@ -242,11 +309,20 @@ index 9135b815..aa01e13b 100644
sigaction(SIGINT, &sa, &oldint);
sigaction(SIGQUIT, &sa, &oldquit);
+diff --git a/src/stdio/popen.c b/src/stdio/popen.c
+index 92cb57ee..70c5d6ec 100644
+--- a/src/stdio/popen.c
++++ b/src/stdio/popen.c
+@@ -1,3 +1,4 @@
++#define _GNU_SOURCE
+ #include <fcntl.h>
+ #include <unistd.h>
+ #include <errno.h>
diff --git a/src/thread/pthread_attr_setinheritsched.c b/src/thread/pthread_attr_setinheritsched.c
-index e540e846..4115e2fe 100644
+index ca264be7..fbfff6f8 100644
--- a/src/thread/pthread_attr_setinheritsched.c
+++ b/src/thread/pthread_attr_setinheritsched.c
-@@ -23,7 +23,7 @@ void *__start_sched(void *p)
+@@ -3,7 +3,7 @@
int pthread_attr_setinheritsched(pthread_attr_t *a, int inherit)
{
@@ -267,11 +343,24 @@ index 46b520c0..933bdb38 100644
+ return ENOTSUP;
}
}
+diff --git a/src/time/strftime.c b/src/time/strftime.c
+index cc53d536..98caa1f6 100644
+--- a/src/time/strftime.c
++++ b/src/time/strftime.c
+@@ -95,6 +95,8 @@ const char *__strftime_fmt_1(char (*s)[100], size_t *l, int f, const struct tm *
+ case 'H':
+ val = tm->tm_hour;
+ goto number;
++ case 'l':
++ def_pad = ' ';
+ case 'I':
+ val = tm->tm_hour;
+ if (!val) val = 12;
diff --git a/src/time/timespec_get.c b/src/time/timespec_get.c
-index 03c5a77b..c423b825 100644
+index 40ea9c1c..6ba68559 100644
--- a/src/time/timespec_get.c
+++ b/src/time/timespec_get.c
-@@ -6,7 +6,7 @@ int __clock_gettime(clockid_t, struct timespec *);
+@@ -4,7 +4,7 @@
* are considered erroneous. */
int timespec_get(struct timespec * ts, int base)
{
@@ -280,6 +369,15 @@ index 03c5a77b..c423b825 100644
int ret = __clock_gettime(CLOCK_REALTIME, ts);
return ret < 0 ? 0 : base;
}
+diff --git a/src/unistd/faccessat.c b/src/unistd/faccessat.c
+index 76bbd4c7..0b4564f9 100644
+--- a/src/unistd/faccessat.c
++++ b/src/unistd/faccessat.c
+@@ -1,3 +1,4 @@
++#define _GNU_SOURCE
+ #include <unistd.h>
+ #include <fcntl.h>
+ #include <sys/wait.h>
diff --git a/src/unistd/getcwd.c b/src/unistd/getcwd.c
index f407ffe0..4fd3a60c 100644
--- a/src/unistd/getcwd.c
@@ -297,92 +395,105 @@ index f407ffe0..4fd3a60c 100644
if (ret == 0 || buf[0] != '/') {
errno = ENOENT;
return 0;
-diff --git a/src/conf/fpathconf.c b/src/conf/fpathconf.c
-index b6a9d63e..83e47e87 100644
---- a/src/conf/fpathconf.c
-+++ b/src/conf/fpathconf.c
-@@ -5,7 +5,7 @@
- long fpathconf(int fd, int name)
- {
- static const long values[] = {
-- [_PC_LINK_MAX] = _POSIX_LINK_MAX,
-+ [_PC_LINK_MAX] = -1,
- [_PC_MAX_CANON] = _POSIX_MAX_CANON,
- [_PC_MAX_INPUT] = _POSIX_MAX_INPUT,
- [_PC_NAME_MAX] = NAME_MAX,
-diff --git a/include/unistd.h b/include/unistd.h
-index 1bdd3292..cdb16c19 100644
---- a/include/unistd.h
-+++ b/include/unistd.h
-@@ -33,16 +33,23 @@ extern "C" {
- #include <bits/alltypes.h>
-
- int pipe(int [2]);
--int pipe2(int [2], int);
- int close(int);
--int posix_close(int, int);
- int dup(int);
- int dup2(int, int);
--int dup3(int, int, int);
- off_t lseek(int, off_t, int);
- int fsync(int);
- int fdatasync(int);
+diff --git a/src/unistd/renameat.c b/src/unistd/renameat.c
+index c3b40a25..e2f03d39 100644
+--- a/src/unistd/renameat.c
++++ b/src/unistd/renameat.c
+@@ -1,11 +1,93 @@
++#include <errno.h>
++#include <fcntl.h>
++#include <libgen.h>
++#include <limits.h>
+ #include <stdio.h>
++#include <string.h>
++#include <sys/stat.h>
++#include <sys/types.h>
++#include <unistd.h>
+ #include "syscall.h"
-+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) \
-+ || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE+0 > 700) \
-+ || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE+0 > 200809L)
-+int pipe2(int [2], int);
-+int dup3(int, int, int);
-+int posix_close(int, int);
++static inline int test_symlink_dirness(int fd, const char *pathname)
++{
++ struct stat statbuf;
++ if (fstatat(fd, pathname, &statbuf, AT_SYMLINK_NOFOLLOW) == -1) {
++ return 1;
++ }
++ if (S_ISLNK(statbuf.st_mode)) {
++ if (fstatat(fd, pathname, &statbuf, 0) == -1) return 1;
+
-+#define POSIX_CLOSE_RESTART 0
-+#endif
++ if (S_ISDIR(statbuf.st_mode)) return 0;
++ else {
++ errno = ENOTDIR;
++ return -1;
++ }
++ }
++ return 1;
++}
+
- ssize_t read(int, void *, size_t);
- ssize_t write(int, const void *, size_t);
- ssize_t pread(int, void *, size_t, off_t);
-@@ -200,8 +207,6 @@ int eaccess(const char *, int);
- #define off64_t off_t
- #endif
-
--#define POSIX_CLOSE_RESTART 0
--
- #define _XOPEN_VERSION 700
- #define _XOPEN_UNIX 1
- #define _XOPEN_ENH_I18N 1
-diff --git a/src/misc/forkpty.c b/src/misc/forkpty.c
-index caf13adb..047eb7d6 100644
---- a/src/misc/forkpty.c
-+++ b/src/misc/forkpty.c
-@@ -1,3 +1,4 @@
-+#define _GNU_SOURCE
- #include <pty.h>
- #include <utmp.h>
- #include <unistd.h>
-diff --git a/src/misc/wordexp.c b/src/misc/wordexp.c
-index db83a69f..1ae03f9f 100644
---- a/src/misc/wordexp.c
-+++ b/src/misc/wordexp.c
-@@ -1,3 +1,4 @@
-+#define _GNU_SOURCE
- #include <wordexp.h>
- #include <unistd.h>
- #include <stdio.h>
-diff --git a/src/stdio/popen.c b/src/stdio/popen.c
-index 92cb57ee..1ff9e0d9 100644
---- a/src/stdio/popen.c
-+++ b/src/stdio/popen.c
-@@ -1,3 +1,4 @@
-+#define _GNU_SOURCE
- #include <fcntl.h>
- #include <unistd.h>
- #include <errno.h>
-diff --git a/src/unistd/faccessat.c b/src/unistd/faccessat.c
-index 76bbd4c7..d5e70608 100644
---- a/src/unistd/faccessat.c
-+++ b/src/unistd/faccessat.c
-@@ -1,3 +1,4 @@
-+#define _GNU_SOURCE
- #include <unistd.h>
- #include <fcntl.h>
- #include <sys/wait.h>
+ int renameat(int oldfd, const char *old, int newfd, const char *new)
+ {
+-#ifdef SYS_renameat
++ char old_copy[PATH_MAX+1], new_copy[PATH_MAX+1];
++ char *base;
++ size_t old_size, new_size;
++ struct stat oldstat, newstat;
++ int r;
++
++ if ((old_size = strlen(old)) > PATH_MAX || \
++ (new_size = strlen(new)) > PATH_MAX) {
++ errno = ENAMETOOLONG;
++ return -1;
++ }
++
++ if (old_size == 0 || new_size == 0) {
++ errno = ENOENT;
++ return -1;
++ }
++
++ /* Test equality of old and new.
++ If they both resolve to the same dentry, we do nothing. */
++ if (fstatat(oldfd, old, &oldstat, 0) == 0 && \
++ fstatat(newfd, new, &newstat, 0) == 0 && \
++ oldstat.st_dev == newstat.st_dev && \
++ oldstat.st_ino == newstat.st_ino) return 0;
++
++ strcpy(old_copy, old);
++ strcpy(new_copy, new);
++
++ base = basename(old_copy);
++ strncpy(old_copy, base, sizeof(old_copy));
++ base = basename(new_copy);
++ strncpy(new_copy, base, sizeof(new_copy));
++
++ if (strcmp(old_copy, ".") == 0 || strcmp(old_copy, "..") == 0 ||
++ strcmp(new_copy, ".") == 0 || strcmp(new_copy, "..") == 0) {
++ errno = EINVAL;
++ return -1;
++ }
++
++ /* The Linux kernel will fail when attempting to rename a symlink of a
++ directory with a trailing slash. We therefore have to handle this
++ case ourselves. */
++ if (old[old_size - 1] == '/') {
++ /* Calling stat(2) on a symlink to a dir with the trailing
++ slash causes stat(2) to return the actual directory instead
++ of the symlink itself. */
++ strcpy(old_copy, old);
++ old_copy[old_size - 1] = '\0';
++ r = test_symlink_dirness(oldfd, old_copy);
++ if (r == 0) old = old_copy;
++ else if (r == -1) return -1;
++ }
++
++ if (new[new_size - 1] == '/') {
++ strcpy(new_copy, new);
++ new_copy[new_size - 1] = '\0';
++ r = test_symlink_dirness(newfd, new_copy);
++ if (r == 0) new = new_copy;
++ else if (r == -1) return -1;
++ }
++
+ return syscall(SYS_renameat, oldfd, old, newfd, new);
+-#else
+- return syscall(SYS_renameat2, oldfd, old, newfd, new, 0);
+-#endif
+ }
diff --git a/system/musl/strftime-add-l-support.patch b/system/musl/strftime-add-l-support.patch
deleted file mode 100644
index 8305a9910..000000000
--- a/system/musl/strftime-add-l-support.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 481def0e92ebfe81f40f416ddf345de15647e46b Mon Sep 17 00:00:00 2001
-From: "A. Wilcox" <AWilcox@Wilcox-Tech.com>
-Date: Fri, 31 May 2019 19:03:20 -0500
-Subject: [PATCH] strftime: add %l support
-
----
- src/time/strftime.c | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/src/time/strftime.c b/src/time/strftime.c
-index cc53d536..98caa1f6 100644
---- a/src/time/strftime.c
-+++ b/src/time/strftime.c
-@@ -95,6 +95,8 @@ const char *__strftime_fmt_1(char (*s)[100], size_t *l, int f, const struct tm *
- case 'H':
- val = tm->tm_hour;
- goto number;
-+ case 'l':
-+ def_pad = ' ';
- case 'I':
- val = tm->tm_hour;
- if (!val) val = 12;
---
-2.21.0
-