b/libs/musl/patches/0003-fix-failure-of-glob-to-match-broken-symlinks-under-s.patch
new file mode 100644
index 0000000..6e5ad21
--- /dev/null
+++
b/libs/musl/patches/0003-fix-failure-of-glob-to-match-broken-symlinks-under-s.patch
@@ -0,0 +1,62 @@
+From 270466ce65707b0c5138e1b5966a01189ed6a655 Mon Sep 17 00:00:00 2001
+From: Rich Felker <dalias AT aerifal.cx>
+Date: Thu, 11 Jul 2019 16:55:17 -0400
+Subject: [PATCH 3/6] fix failure of glob to match broken symlinks under some
+ conditions
+
+when the pattern ended with one or more literal path components, or
+when the GLOB_MARK flag was passed to request that glob flag directory
+results and the type obtained by readdir was unknown or inconclusive
+(symlink), the stat function was called to evaluate existence and/or
+determine type. however, stat fails with ENOENT for broken symlinks,
+and this caused the match to be omitted from the results.
+
+instead, use stat only for the unknown/inconclusive cases with
+GLOB_MARK, and otherwise, or if stat fails, use lstat existence still
+needs to be determined. this minimizes the number of costly syscalls,
+performing both only in the case where GLOB_MARK is in use and there
+is a final literal path component which is a broken symlink.
+
+based on/simplified from patch by James Y Knight.
+
+Signed-off-by: Ismael Luceno <ismael AT iodev.co.uk>
+---
+ src/regex/glob.c | 17 ++++++++++++-----
+ 1 file changed, 12 insertions(+), 5 deletions(-)
+
+diff --git a/src/regex/glob.c b/src/regex/glob.c
+index 58248675c203..9de080ed9ccd 100644
+--- a/src/regex/glob.c
++++ b/src/regex/glob.c
+@@ -92,16 +92,23 @@ static int do_glob(char *buf, size_t pos, int type, char
*pat, int flags, int (*
+ if (!*pat) {
+ /* If we consumed any components above, or if GLOB_MARK is
+ * requested and we don't yet know if the match is a dir,
+- * we must call stat to confirm the file exists and/or
+- * determine its type. */
++ * we must confirm the file exists and/or determine its type.
++ *
++ * If marking dirs, symlink type is inconclusive; we need the
++ * type for the symlink target, and therefore must try stat
++ * first unless type is known not to be a symlink. Otherwise,
++ * or if that fails, use lstat for determining existence to
++ * avoid false negatives in the case of broken symlinks. */
+ struct stat st;
+- if ((flags & GLOB_MARK) && type==DT_LNK) type = 0;
+- if (!type && stat(buf, &st)) {
++ if ((flags & GLOB_MARK) && (!type||type==DT_LNK) &&
!stat(buf, &st)) {
++ if (S_ISDIR(st.st_mode)) type = DT_DIR;
++ else type = DT_REG;
++ }
++ if (!type && lstat(buf, &st)) {
+ if (errno!=ENOENT && (errfunc(buf, errno) || (flags &
GLOB_ERR)))
+ return GLOB_ABORTED;
+ return 0;
+ }
+- if (!type && S_ISDIR(st.st_mode)) type = DT_DIR;
+ if (append(tail, buf, pos, (flags & GLOB_MARK) &&
type==DT_DIR))
+ return GLOB_NOSPACE;
+ return 0;
+--
+2.22.0
+
diff --git a/libs/musl/patches/0004-glob-implement-GLOB_NOMAGIC.patch
b/libs/musl/patches/0004-glob-implement-GLOB_NOMAGIC.patch
new file mode 100644
index 0000000..53ec2af
--- /dev/null
+++ b/libs/musl/patches/0004-glob-implement-GLOB_NOMAGIC.patch
@@ -0,0 +1,53 @@
+From 5d89738649095a36f584ec30a59c945c8191593e Mon Sep 17 00:00:00 2001
+From: Ismael Luceno <ismael AT iodev.co.uk>
+Date: Fri, 26 Jul 2019 18:13:14 +0200
+Subject: [PATCH 4/6] glob: implement GLOB_NOMAGIC
+
+Signed-off-by: Ismael Luceno <ismael AT iodev.co.uk>
+---
+ include/glob.h | 1 +
+ src/regex/glob.c | 13 +++++++++----
+ 2 files changed, 10 insertions(+), 4 deletions(-)
+
+diff --git a/include/glob.h b/include/glob.h
+index 4a562a206d52..0ff70bdfeef2 100644
+--- a/include/glob.h
++++ b/include/glob.h
+@@ -31,6 +31,7 @@ void globfree(glob_t *);
+ #define GLOB_NOESCAPE 0x40
+ #define GLOB_PERIOD 0x80
+
++#define GLOB_NOMAGIC 0x0800
+ #define GLOB_TILDE 0x1000
+ #define GLOB_TILDE_CHECK 0x4000
+
+diff --git a/src/regex/glob.c b/src/regex/glob.c
+index 9de080ed9ccd..7780e21ee113 100644
+--- a/src/regex/glob.c
++++ b/src/regex/glob.c
+@@ -260,13 +260,18 @@ int glob(const char *restrict pat, int flags, int
(*errfunc)(const char *path, i
+
+ for (cnt=0, tail=head.next; tail; tail=tail->next, cnt++);
+ if (!cnt) {
++ size_t len;
+ if (flags & GLOB_NOCHECK) {
+- tail = &head;
+- if (append(&tail, pat, strlen(pat), 0))
+- return GLOB_NOSPACE;
+- cnt++;
++ len = strlen(pat);
++ } else if (flags & GLOB_NOMAGIC) {
++ len = strcspn(pat, "*?[");
++ if (pat[len]) return GLOB_NOMATCH;
+ } else
+ return GLOB_NOMATCH;
++ tail = &head;
++ if (append(&tail, pat, len, 0))
++ return GLOB_NOSPACE;
++ cnt++;
+ }
+
+ if (flags & GLOB_APPEND) {
+--
+2.22.0
+
diff --git
a/libs/musl/patches/0005-add-internal-aliases-__opendir-__readdir-and-__close.patch
b/libs/musl/patches/0005-add-internal-aliases-__opendir-__readdir-and-__close.patch
new file mode 100644
index 0000000..9049d18
--- /dev/null
+++
b/libs/musl/patches/0005-add-internal-aliases-__opendir-__readdir-and-__close.patch
@@ -0,0 +1,89 @@
+From d660a4f71cb5a4cbfbdce6ffc0f8ffdbe80db7d5 Mon Sep 17 00:00:00 2001
+From: Ismael Luceno <ismael AT iodev.co.uk>
+Date: Thu, 1 Aug 2019 15:26:46 +0200
+Subject: [PATCH 5/6] add internal aliases __opendir, __readdir and __closedir
+
+Signed-off-by: Ismael Luceno <ismael AT iodev.co.uk>
+---
+ src/dirent/closedir.c | 4 +++-
+ src/dirent/opendir.c | 4 +++-
+ src/dirent/readdir.c | 5 +++--
+ src/include/dirent.h | 10 ++++++++++
+ 4 files changed, 19 insertions(+), 4 deletions(-)
+ create mode 100644 src/include/dirent.h
+
+diff --git a/src/dirent/closedir.c b/src/dirent/closedir.c
+index e794ae9ca44b..f4249f56e210 100644
+--- a/src/dirent/closedir.c
++++ b/src/dirent/closedir.c
+@@ -3,9 +3,11 @@
+ #include <stdlib.h>
+ #include "__dirent.h"
+
+-int closedir(DIR *dir)
++int __closedir(DIR *dir)
+ {
+ int ret = close(dir->fd);
+ free(dir);
+ return ret;
+ }
++
++weak_alias(__closedir, closedir);
+diff --git a/src/dirent/opendir.c b/src/dirent/opendir.c
+index 5cb84e303fee..4123c81994cd 100644
+--- a/src/dirent/opendir.c
++++ b/src/dirent/opendir.c
+@@ -5,7 +5,7 @@
+ #include "__dirent.h"
+ #include "syscall.h"
+
+-DIR *opendir(const char *name)
++DIR *__opendir(const char *name)
+ {
+ int fd;
+ DIR *dir;
+@@ -19,3 +19,5 @@ DIR *opendir(const char *name)
+ dir->fd = fd;
+ return dir;
+ }
++
++weak_alias(__opendir, opendir);
+diff --git a/src/dirent/readdir.c b/src/dirent/readdir.c
+index 569fc7057737..cb34a258569c 100644
+--- a/src/dirent/readdir.c
++++ b/src/dirent/readdir.c
+@@ -7,7 +7,7 @@
+ typedef char dirstream_buf_alignment_check[1-2*(int)(
+ offsetof(struct __dirstream, buf) % sizeof(off_t))];
+
+-struct dirent *readdir(DIR *dir)
++struct dirent *__readdir(DIR *dir)
+ {
+ struct dirent *de;
+
+@@ -26,4 +26,5 @@ struct dirent *readdir(DIR *dir)
+ return de;
+ }
+
+-weak_alias(readdir, readdir64);
++weak_alias(__readdir, readdir64);
++weak_alias(__readdir, readdir);
+diff --git a/src/include/dirent.h b/src/include/dirent.h
+new file mode 100644
+index 000000000000..918e123566d4
+--- /dev/null
++++ b/src/include/dirent.h
+@@ -0,0 +1,10 @@
++#ifndef DIRENT_H
++#define DIRENT_H
++
++#include "../../include/dirent.h"
++
++hidden int __closedir(DIR *);
++hidden DIR *__opendir(const char *);
++hidden struct dirent *__readdir(DIR *);
++
++#endif
+--
+2.22.0
+
diff --git
a/libs/musl/patches/0006-glob-implement-GLOB_ALTDIRFUNC-et-al.patch
b/libs/musl/patches/0006-glob-implement-GLOB_ALTDIRFUNC-et-al.patch
new file mode 100644
index 0000000..0372778
--- /dev/null
+++ b/libs/musl/patches/0006-glob-implement-GLOB_ALTDIRFUNC-et-al.patch
@@ -0,0 +1,173 @@
+From a0d46379e577a3a9cf4d3fc3582bb6000f43c058 Mon Sep 17 00:00:00 2001
+From: Ismael Luceno <ismael AT iodev.co.uk>
+Date: Tue, 30 Jul 2019 21:48:31 +0200
+Subject: [PATCH 6/6] glob: implement GLOB_ALTDIRFUNC et al
+
+Signed-off-by: Ismael Luceno <ismael AT iodev.co.uk>
+---
+ include/glob.h | 8 +++++++-
+ src/regex/glob.c | 47 +++++++++++++++++++++++++++++++++++++----------
+ 2 files changed, 44 insertions(+), 11 deletions(-)
+
+diff --git a/include/glob.h b/include/glob.h
+index 0ff70bdfeef2..0db4780f6a00 100644
+--- a/include/glob.h
++++ b/include/glob.h
+@@ -16,7 +16,12 @@ typedef struct {
+ char **gl_pathv;
+ size_t gl_offs;
+ int __dummy1;
+- void *__dummy2[5];
++
++ void (*gl_closedir)(void *);
++ struct dirent *(*gl_readdir)(void *);
++ void *(*gl_opendir)(const char *);
++ int (*gl_lstat)(const char *__restrict, struct stat *__restrict);
++ int (*gl_stat)(const char *__restrict, struct stat *__restrict);
+ } glob_t;
+
+ int glob(const char *__restrict, int, int (*)(const char *, int), glob_t
*__restrict);
+@@ -31,6 +36,7 @@ void globfree(glob_t *);
+ #define GLOB_NOESCAPE 0x40
+ #define GLOB_PERIOD 0x80
+
++#define GLOB_ALTDIRFUNC 0x0200
+ #define GLOB_NOMAGIC 0x0800
+ #define GLOB_TILDE 0x1000
+ #define GLOB_TILDE_CHECK 0x4000
+diff --git a/src/regex/glob.c b/src/regex/glob.c
+index 7780e21ee113..4f329f053fe0 100644
+--- a/src/regex/glob.c
++++ b/src/regex/glob.c
+@@ -1,7 +1,7 @@
+ #define _BSD_SOURCE
++#include <sys/stat.h>
+ #include <glob.h>
+ #include <fnmatch.h>
+-#include <sys/stat.h>
+ #include <dirent.h>
+ #include <limits.h>
+ #include <string.h>
+@@ -11,6 +11,14 @@
+ #include <unistd.h>
+ #include <pwd.h>
+
++struct dirfn {
++ void (*closedir)(void *);
++ struct dirent *(*readdir)(void *);
++ void *(*opendir)(const char *);
++ int (*lstat)(const char *restrict, struct stat *restrict);
++ int (*stat)(const char *restrict, struct stat *restrict);
++};
++
+ struct match
+ {
+ struct match *next;
+@@ -32,7 +40,7 @@ static int append(struct match **tail, const char *name,
size_t len, int mark)
+ return 0;
+ }
+
+-static int do_glob(char *buf, size_t pos, int type, char *pat, int flags,
int (*errfunc)(const char *path, int err), struct match **tail)
++static int do_glob(char *buf, size_t pos, int type, char *pat, int flags,
int (*errfunc)(const char *path, int err), const struct dirfn * const
restrict dirfn, struct match **tail)
+ {
+ /* If GLOB_MARK is unused, we don't care about type. */
+ if (!type && !(flags & GLOB_MARK)) type = DT_REG;
+@@ -100,11 +108,11 @@ static int do_glob(char *buf, size_t pos, int type,
char *pat, int flags, int (*
+ * or if that fails, use lstat for determining existence to
+ * avoid false negatives in the case of broken symlinks. */
+ struct stat st;
+- if ((flags & GLOB_MARK) && (!type||type==DT_LNK) &&
!stat(buf, &st)) {
++ if ((flags & GLOB_MARK) && (!type||type==DT_LNK) &&
!dirfn->stat(buf, &st)) {
+ if (S_ISDIR(st.st_mode)) type = DT_DIR;
+ else type = DT_REG;
+ }
+- if (!type && lstat(buf, &st)) {
++ if (!type && dirfn->lstat(buf, &st)) {
+ if (errno!=ENOENT && (errfunc(buf, errno) || (flags &
GLOB_ERR)))
+ return GLOB_ABORTED;
+ return 0;
+@@ -124,7 +132,7 @@ static int do_glob(char *buf, size_t pos, int type, char
*pat, int flags, int (*
+ saved_sep = '\\';
+ }
+ }
+- DIR *dir = opendir(pos ? buf : ".");
++ DIR *dir = dirfn->opendir(pos ? buf : ".");
+ if (!dir) {
+ if (errfunc(buf, errno) || (flags & GLOB_ERR))
+ return GLOB_ABORTED;
+@@ -132,7 +140,7 @@ static int do_glob(char *buf, size_t pos, int type, char
*pat, int flags, int (*
+ }
+ int old_errno = errno;
+ struct dirent *de;
+- while (errno=0, de=readdir(dir)) {
++ while (errno=0, de=dirfn->readdir(dir)) {
+ /* Quickly skip non-directories when there's pattern left. */
+ if (p2 && de->d_type && de->d_type!=DT_DIR &&
de->d_type!=DT_LNK)
+ continue;
+@@ -157,15 +165,15 @@ static int do_glob(char *buf, size_t pos, int type,
char *pat, int flags, int (*
+
+ memcpy(buf+pos, de->d_name, l+1);
+ if (p2) *p2 = saved_sep;
+- int r = do_glob(buf, pos+l, de->d_type, p2 ? p2 : "", flags,
errfunc, tail);
++ int r = do_glob(buf, pos+l, de->d_type, p2 ? p2 : "", flags,
errfunc, dirfn, tail);
+ if (r) {
+- closedir(dir);
++ dirfn->closedir(dir);
+ return r;
+ }
+ }
+ int readerr = errno;
+ if (p2) *p2 = saved_sep;
+- closedir(dir);
++ dirfn->closedir(dir);
+ if (readerr && (errfunc(buf, errno) || (flags & GLOB_ERR)))
+ return GLOB_ABORTED;
+ errno = old_errno;
+@@ -224,6 +232,10 @@ static int expand_tilde(char **pat, char *buf, size_t
*pos)
+ return 0;
+ }
+
++static void wrap_closedir(void *p) { __closedir(p); }
++static struct dirent *wrap_readdir(void *d) { return __readdir(d); }
++static void *wrap_opendir(const char *path) { return __opendir(path); }
++
+ int glob(const char *restrict pat, int flags, int (*errfunc)(const char
*path, int err), glob_t *restrict g)
+ {
+ struct match head = { .next = NULL }, *tail = &head;
+@@ -231,9 +243,24 @@ int glob(const char *restrict pat, int flags, int
(*errfunc)(const char *path, i
+ size_t offs = (flags & GLOB_DOOFFS) ? g->gl_offs : 0;
+ int error = 0;
+ char buf[PATH_MAX];
++ struct dirfn dirfn;
+
+ if (!errfunc) errfunc = ignore_err;
+
++ if (flags & GLOB_ALTDIRFUNC) {
++ dirfn.closedir = g->gl_closedir;
++ dirfn.readdir = g->gl_readdir;
++ dirfn.opendir = g->gl_opendir;
++ dirfn.lstat = g->gl_lstat;
++ dirfn.stat = g->gl_stat;
++ } else {
++ dirfn.closedir = wrap_closedir;
++ dirfn.readdir = wrap_readdir;
++ dirfn.opendir = wrap_opendir;
++ dirfn.lstat = lstat;
++ dirfn.stat = stat;
++ }
++
+ if (!(flags & GLOB_APPEND)) {
+ g->gl_offs = offs;
+ g->gl_pathc = 0;
+@@ -249,7 +276,7 @@ int glob(const char *restrict pat, int flags, int
(*errfunc)(const char *path, i
+ if ((flags & (GLOB_TILDE | GLOB_TILDE_CHECK)) && *p == '~')
+ error = expand_tilde(&s, buf, &pos);
+ if (!error)
+- error = do_glob(buf, pos, 0, s, flags, errfunc,
&tail);
++ error = do_glob(buf, pos, 0, s, flags, errfunc,
&dirfn, &tail);
+ free(p);
+ }
+
+--
+2.22.0
+
[SM-Commit] GIT changes to master grimoire by Ismael Luceno (ae7821ed8784d1898e541a40fdd56b431a4ef3ee),
Ismael Luceno, 08/16/2019