This commit is contained in:
Kevin Boulain 2025-11-22 11:08:41 +09:00 committed by GitHub
commit e086682305
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 93 additions and 71 deletions

View file

@ -1405,6 +1405,7 @@ pub const MiscTask = enum {
analyze_mod, analyze_mod,
docs_copy, docs_copy,
docs_wasm, docs_wasm,
cachedir_tag,
@"musl crt1.o", @"musl crt1.o",
@"musl rcrt1.o", @"musl rcrt1.o",
@ -4587,6 +4588,8 @@ fn performAllTheWork(
comp.link_prog_node.increaseEstimatedTotalItems(comp.link_task_queue.queued_prelink.items.len); comp.link_prog_node.increaseEstimatedTotalItems(comp.link_task_queue.queued_prelink.items.len);
comp.link_task_queue.start(comp); comp.link_task_queue.start(comp);
comp.thread_pool.spawnWg(&work_queue_wait_group, workerTagCacheDirs, .{comp});
if (comp.emit_docs != null) { if (comp.emit_docs != null) {
dev.check(.docs_emit); dev.check(.docs_emit);
comp.thread_pool.spawnWg(&work_queue_wait_group, workerDocsCopy, .{comp}); comp.thread_pool.spawnWg(&work_queue_wait_group, workerDocsCopy, .{comp});
@ -5481,6 +5484,29 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) SubU
}; };
} }
fn workerTagCacheDirs(comp: *Compilation) void {
for (&[_]Cache.Directory{ comp.dirs.global_cache, comp.dirs.local_cache }) |dir| {
tagCacheDir(dir.handle) catch |err| {
return comp.lockAndSetMiscFailure(
.cachedir_tag,
"unable to create CACHEDIR.TAG file in '{f}': {s}",
.{ dir, @errorName(err) },
);
};
}
}
fn tagCacheDir(dir: fs.Dir) !void {
const file = try dir.createFile("CACHEDIR.TAG", .{});
defer file.close();
try file.writeAll(
\\Signature: 8a477f597d28d172789f06886806bc55
\\# This file is a cache directory tag created by Zig.
\\# For information about cache directory tags, see: http://www.brynosaurus.com/cachedir/
\\
);
}
fn workerUpdateFile( fn workerUpdateFile(
tid: usize, tid: usize,
comp: *Compilation, comp: *Compilation,

View file

@ -4,9 +4,9 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
static void panic(const char *reason) { #define panic(REASON) do { \
fprintf(stderr, "%s\n", reason); fprintf(stderr, "%s:%d: %s\n", __func__, __LINE__, REASON); \
abort(); abort(); \
} } while (0)
#endif /* PANIC_H */ #endif /* PANIC_H */

View file

@ -399,6 +399,49 @@ static void DirEntry_unlink(uint32_t de) {
des[de].host_path = NULL; des[de].host_path = NULL;
} }
static enum wasi_errno FileDescriptor_open(uint32_t de, uint32_t oflags, uint64_t fs_rights_base, uint32_t fdflags, FILE **stream) {
const bool creat = (oflags & wasi_oflags_creat) != 0;
const bool excl = (oflags & wasi_oflags_excl) != 0;
const bool trunc = (oflags & wasi_oflags_trunc) != 0;
const bool append = (fdflags & wasi_fdflags_append) != 0;
switch (des[de].filetype) {
case wasi_filetype_directory:
case wasi_filetype_regular_file:
break;
default: panic("unimplemented");
}
if (des[de].host_path == NULL) {
if (!creat) return wasi_errno_noent;
*stream = NULL;
} else {
if (oflags != (append ? wasi_oflags_creat : wasi_oflags_creat | wasi_oflags_trunc)) {
char mode[] = "rb+";
if ((fs_rights_base & wasi_rights_fd_write) == 0) mode[2] = '\0';
*stream = fopen(des[de].host_path, mode);
if (*stream != NULL) {
if (append || excl || trunc) fclose(*stream);
if (excl) return wasi_errno_exist;
} else if (!creat) return wasi_errno_noent;
}
if (append || trunc || *stream == NULL) {
char mode[] = "wb+";
if ((fs_rights_base & wasi_rights_fd_read) == 0) mode[2] = '\0';
if (trunc || !append) {
*stream = fopen(des[de].host_path, mode);
if (append && *stream != NULL) fclose(*stream);
}
if (append) {
mode[0] = 'a';
*stream = fopen(des[de].host_path, mode);
}
}
if (*stream == NULL) return wasi_errno_isdir;
}
return wasi_errno_success;
}
uint32_t wasi_snapshot_preview1_args_sizes_get(uint32_t argv_size, uint32_t argv_buf_size) { uint32_t wasi_snapshot_preview1_args_sizes_get(uint32_t argv_size, uint32_t argv_buf_size) {
uint8_t *const m = *wasm_memory; uint8_t *const m = *wasm_memory;
uint32_t *argv_size_ptr = (uint32_t *)&m[argv_size]; uint32_t *argv_size_ptr = (uint32_t *)&m[argv_size];
@ -813,82 +856,35 @@ uint32_t wasi_snapshot_preview1_path_open(uint32_t fd, uint32_t dirflags, uint32
fprintf(stderr, "wasi_snapshot_preview1_path_open(%u, 0x%X, \"%.*s\", 0x%X, 0x%llX, 0x%llX, 0x%X)\n", fd, dirflags, (int)path_len, path_ptr, oflags, (unsigned long long)fs_rights_base, (unsigned long long)fs_rights_inheriting, fdflags); fprintf(stderr, "wasi_snapshot_preview1_path_open(%u, 0x%X, \"%.*s\", 0x%X, 0x%llX, 0x%llX, 0x%X)\n", fd, dirflags, (int)path_len, path_ptr, oflags, (unsigned long long)fs_rights_base, (unsigned long long)fs_rights_inheriting, fdflags);
#endif #endif
bool creat = (oflags & wasi_oflags_creat) != 0; const bool directory = (oflags & wasi_oflags_directory) != 0;
bool directory = (oflags & wasi_oflags_directory) != 0;
bool excl = (oflags & wasi_oflags_excl) != 0;
bool trunc = (oflags & wasi_oflags_trunc) != 0;
bool append = (fdflags & wasi_fdflags_append) != 0;
uint32_t de; uint32_t de;
enum wasi_errno lookup_errno = DirEntry_lookup(fd, dirflags, path_ptr, path_len, &de); const enum wasi_errno lookup_errno = DirEntry_lookup(fd, dirflags, path_ptr, path_len, &de);
if (lookup_errno == wasi_errno_success) { if (lookup_errno != wasi_errno_success && lookup_errno != wasi_errno_noent) return lookup_errno;
if (directory && des[de].filetype != wasi_filetype_directory) return wasi_errno_notdir; if (lookup_errno == wasi_errno_success && directory && des[de].filetype != wasi_filetype_directory) return wasi_errno_notdir;
struct FileDescriptor *new_fds = realloc(fds, (fd_len + 1) * sizeof(struct FileDescriptor));
if (new_fds == NULL) return wasi_errno_nomem;
fds = new_fds;
fds[fd_len].de = de;
fds[fd_len].fdflags = fdflags;
switch (des[de].filetype) {
case wasi_filetype_directory: fds[fd_len].stream = NULL; break;
default: panic("unimplemented: path_open non-directory DirEntry");
}
fds[fd_len].fs_rights_inheriting = fs_rights_inheriting;
#if LOG_TRACE
fprintf(stderr, "fd = %u\n", fd_len);
#endif
store32_align2(res_fd_ptr, fd_len);
fd_len += 1;
}
if (lookup_errno != wasi_errno_noent) return lookup_errno;
struct FileDescriptor *new_fds = realloc(fds, (fd_len + 1) * sizeof(struct FileDescriptor)); struct FileDescriptor *new_fds = realloc(fds, (fd_len + 1) * sizeof(struct FileDescriptor));
if (new_fds == NULL) return wasi_errno_nomem; if (new_fds == NULL) return wasi_errno_nomem;
fds = new_fds; fds = new_fds;
enum wasi_filetype filetype = directory ? wasi_filetype_directory : wasi_filetype_regular_file; if (lookup_errno == wasi_errno_noent) {
enum wasi_errno create_errno = DirEntry_create(fd, path_ptr, path_len, filetype, 0, &de); enum wasi_filetype filetype = directory ? wasi_filetype_directory : wasi_filetype_regular_file;
if (create_errno != wasi_errno_success) return create_errno; const enum wasi_errno create_errno = DirEntry_create(fd, path_ptr, path_len, filetype, time(NULL), &de);
if (create_errno != wasi_errno_success) return create_errno;
}
FILE *stream; FILE *stream;
if (!directory) { if (directory) stream = NULL;
if (des[de].host_path == NULL) { else {
if (!creat) { DirEntry_unlink(de); de_len -= 1; return wasi_errno_noent; } const enum wasi_errno open_errno = FileDescriptor_open(de, oflags, fs_rights_base, fdflags, &stream);
time_t now = time(NULL); if (open_errno != wasi_errno_success) {
des[de].atim = now; if (lookup_errno == wasi_errno_noent) {
des[de].mtim = now; DirEntry_unlink(de);
des[de].ctim = now; de_len -= 1;
stream = NULL;
} else {
if (oflags != (append ? wasi_oflags_creat : wasi_oflags_creat | wasi_oflags_trunc)) {
char mode[] = "rb+";
if ((fs_rights_base & wasi_rights_fd_write) == 0) mode[2] = '\0';
stream = fopen(des[de].host_path, mode);
if (stream != NULL) {
if (append || excl || trunc) fclose(stream);
if (excl) {
DirEntry_unlink(de);
de_len -= 1;
return wasi_errno_exist;
}
} else if (!creat) { DirEntry_unlink(de); de_len -= 1; return wasi_errno_noent; }
}
if (append || trunc || stream == NULL) {
char mode[] = "wb+";
if ((fs_rights_base & wasi_rights_fd_read) == 0) mode[2] = '\0';
if (trunc || !append) {
stream = fopen(des[de].host_path, mode);
if (append && stream != NULL) fclose(stream);
}
if (append) {
mode[0] = 'a';
stream = fopen(des[de].host_path, mode);
}
}
if (stream == NULL) { DirEntry_unlink(de); de_len -= 1; return wasi_errno_isdir; }
} }
} else stream = NULL; return open_errno;
}
}
#if LOG_TRACE #if LOG_TRACE
fprintf(stderr, "fd = %u\n", fd_len); fprintf(stderr, "fd = %u\n", fd_len);