···4949#define LINUX_S_IFMT 00170000
5050#define LINUX_S_IFLNK 0120000
51515252-#define __simple_printf(...)
5252+#define __simple_printf __simple_kprintf
53535454#endif
5555···72727373 int symlink_depth;
7474 bool unknown_component;
7575+ bool follow;
7576};
76777778static int vchroot_run(const char* path, struct context* ctxt);
···136137 ctxt.symlink_depth = 0;
137138 ctxt.current_root = prefix_path;
138139 ctxt.current_root_len = prefix_path_len;
140140+ ctxt.follow = !!(args->flags & VCHROOT_FOLLOW);
139141140142 const char* input_path = args->path;
141143···284286 }
285287 else if ((st.st_mode & LINUX_S_IFMT) == LINUX_S_IFLNK)
286288 {
287287- char link[512];
288288- int rv;
289289+ // Follow symlink if follow is true or if we haven't reached the end of the input path yet
290290+ if (ctxt->follow || *end)
291291+ {
292292+ char link[512];
293293+ int rv;
289294290290- rv = LINUX_SYSCALL(__NR_readlink, ctxt->current_path, link, sizeof(link) - 1);
295295+ rv = LINUX_SYSCALL(__NR_readlink, ctxt->current_path, link, sizeof(link) - 1);
291296292292- if (rv < 0)
293293- return rv;
297297+ if (rv < 0)
298298+ return rv;
294299295295- link[rv] = '\0';
300300+ link[rv] = '\0';
296301297297- // Remove the last component (because it will be substituted with symlink contents)
298298- if (link[0] != '/') // Only bother to do that if we know that the symlink is not absolute
299299- {
300300- ctxt->current_path_len = prevlen - 1; // kill the last slash as well
301301- ctxt->current_path[ctxt->current_path_len] = '\0';
302302- }
302302+ // Remove the last component (because it will be substituted with symlink contents)
303303+ if (link[0] != '/') // Only bother to do that if we know that the symlink is not absolute
304304+ {
305305+ ctxt->current_path_len = prevlen - 1; // kill the last slash as well
306306+ ctxt->current_path[ctxt->current_path_len] = '\0';
307307+ }
308308+309309+ // Symbolic link resolution
310310+ const bool orig_follow = ctxt->follow;
311311+312312+ ctxt->follow = true;
313313+ ctxt->symlink_depth++;
314314+315315+ rv = vchroot_run(link, ctxt);
303316304304- // Symbolic link resolution
305305- ctxt->symlink_depth++;
306306- rv = vchroot_run(link, ctxt);
307307- ctxt->symlink_depth--;
317317+ ctxt->symlink_depth--;
318318+ ctxt->follow = orig_follow;
308319309309- if (rv != 0)
310310- return rv;
320320+ if (rv != 0)
321321+ return rv;
322322+ }
311323 }
312324 }
313325
-18
src/setup-fonts.sh
···11-#! /bin/bash
22-33-# This runs as root,
44-# with the current directory set to ${CMAKE_INSTALL_PREFIX}/libexec/darling
55-66-root=/Volumes/SystemRoot
77-88-for file in $(find /etc/fonts/ -type f); do
99- mkdir -p $(dirname .$file)
1010- sed "s|/usr/|$root/usr/|" $file > .$file
1111-done
1212-1313-for link in $(find /etc/fonts/ -type l); do
1414- if [[ ! -L .$link ]]; then
1515- mkdir -p $(dirname .$link)
1616- ln -s $root$(realpath $link) .$link
1717- fi
1818-done
-19
src/setup-ld-so.sh
···11-#! /bin/bash
22-33-# This runs as root,
44-# with the current directory set to ${CMAKE_INSTALL_PREFIX}/libexec/darling
55-66-for file in /etc/ld.so.conf $(find -L /etc/ld.so.conf.d/ -type f); do
77- # Copy lines from e.g. /etc/ld.so.conf into ./etc/ld.so.conf,
88- # prepending "/Volumes/SystemRoot" to each line that starts with a slash
99- awk '/^\// { print "/Volumes/SystemRoot" $0 }; /^[^\/]/' $file > .$file
1010-done
1111-1212-# These are the defaults used by the ELF dynamic linker.
1313-# They don't need to be explicitly listed in /etc/ld.so.conf.
1414-cat > ./etc/ld.so.conf.d/defaults.conf <<END
1515-/Volumes/SystemRoot/lib
1616-/Volumes/SystemRoot/usr/lib
1717-END
1818-1919-unshare --mount bash -c "mount --rbind / Volumes/SystemRoot && ldconfig -r . -X"
+6-1
src/startup/darling.c
···539539 // Connect to the shellspawn daemon in the container
540540 addr.sun_family = AF_UNIX;
541541#if USE_LINUX_4_11_HACK
542542- strcpy(addr.sun_path, SHELLSPAWN_SOCKPATH);
542542+ addr.sun_path[0] = '\0';
543543+544544+ if (g_useVchroot)
545545+ strcpy(addr.sun_path, prefix);
546546+547547+ strcat(addr.sun_path, SHELLSPAWN_SOCKPATH);
543548#else
544549 snprintf(addr.sun_path, sizeof(addr.sun_path), "%s" SHELLSPAWN_SOCKPATH, prefix);
545550#endif