Skip to content

Commit 2d48565

Browse files
motiejusandrewrk
authored andcommitted
wip: address @andrewrk review comments
1 parent 38800e2 commit 2d48565

File tree

4 files changed

+72
-81
lines changed

4 files changed

+72
-81
lines changed

lib/std/Build/Cache.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ pub const Directory = struct {
3131
}
3232
}
3333

34-
pub fn tmpFilePath(self: *const Directory, ally: Allocator, suffix: []const u8) error{OutOfMemory}![]const u8 {
34+
pub fn tmpFilePath(self: Directory, ally: Allocator, suffix: []const u8) error{OutOfMemory}![]const u8 {
3535
const s = std.fs.path.sep_str;
3636
const rand_int = std.crypto.random.int(u64);
3737
if (self.path) |p| {

src/Compilation.zig

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4587,6 +4587,14 @@ pub const FileExt = enum {
45874587
=> false,
45884588
};
45894589
}
4590+
4591+
// maximum length of @tagName(ext: FileExt)
4592+
pub const max_len = blk: {
4593+
var max: u16 = 0;
4594+
inline for (std.meta.tags(FileExt)) |ext|
4595+
max = std.math.max(@tagName(ext).len, max);
4596+
break :blk max;
4597+
};
45904598
};
45914599

45924600
pub fn hasObjectExt(filename: []const u8) bool {

src/main.zig

Lines changed: 22 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -661,34 +661,6 @@ fn optionalStringEnvVar(arena: Allocator, name: []const u8) !?[]const u8 {
661661
}
662662
}
663663

664-
// Read an open file descriptor to a new file in `dst_dir`. Return a file name
665-
// of the new file.
666-
fn copyToFile(
667-
arena: Allocator,
668-
in_fd: std.os.fd_t,
669-
dst_dir: Compilation.Directory,
670-
) ![]const u8 {
671-
const new_name = try dst_dir.tmpFilePath(arena, "waspipe");
672-
try dst_dir.handle.makePath("tmp");
673-
var outfile = try dst_dir.handle.createFile(new_name, .{});
674-
defer outfile.close();
675-
errdefer dst_dir.handle.deleteFile(new_name) catch {};
676-
677-
// gnu tar uses that many bytes for its internal buffer, cargo culting
678-
var buffer: [10240]u8 = undefined;
679-
while (true) {
680-
const amt = try std.os.read(in_fd, buffer[0..]);
681-
if (amt == 0)
682-
break;
683-
684-
var written: usize = 0;
685-
while (written < amt)
686-
written += try std.os.write(outfile.handle, buffer[written..amt]);
687-
}
688-
689-
return new_name;
690-
}
691-
692664
const ArgMode = union(enum) {
693665
build: std.builtin.OutputMode,
694666
cc,
@@ -3043,33 +3015,39 @@ fn buildOutputType(
30433015
break :l global_cache_directory;
30443016
};
30453017

3046-
var temp_files_for_comp = std.ArrayList([]const u8).init(gpa);
3018+
var temp_stdin_file: ?[]const u8 = null;
30473019
defer {
3048-
for (temp_files_for_comp.items) |file| {
3020+
if (temp_stdin_file) |file| {
30493021
// some garbage may stay in the file system if removal fails.
30503022
// Alternatively, we could tell the user that the removal failed,
30513023
// but it's not as much of a deal: it's a temporary cache directory
30523024
// at all.
30533025
local_cache_directory.handle.deleteFile(file) catch {};
30543026
}
3055-
temp_files_for_comp.deinit();
30563027
}
30573028

3058-
// if a c_source_file is "-", dump it to a tempdir and replace the src_name
3059-
// with the newly created file. translate-c works fine with streams; other
3060-
// actions don't.
3061-
if (arg_mode != .translate_c) {
3062-
for (c_source_files.items) |*src| {
3063-
if (!mem.eql(u8, src.src_path, "-")) continue;
3029+
for (c_source_files.items) |*src| {
3030+
if (!mem.eql(u8, src.src_path, "-")) continue;
30643031

3065-
if (src.ext == null)
3066-
fatal("-E or -x is required when reading from a non-regular file", .{});
3032+
const ext = src.ext orelse
3033+
fatal("-E or -x is required when reading from a non-regular file", .{});
30673034

3068-
// "-" is stdin. Dump it to a real file.
3069-
const new_file = try copyToFile(arena, io.getStdIn().handle, local_cache_directory);
3070-
try temp_files_for_comp.append(new_file);
3071-
src.src_path = new_file;
3072-
}
3035+
// "-" is stdin. Dump it to a real file.
3036+
const new_file = blk: {
3037+
var buf: ["stdin.".len + Compilation.FileExt.max_len]u8 = undefined;
3038+
const fname = try std.fmt.bufPrint(&buf, "stdin.{s}", .{@tagName(ext)});
3039+
const new_name = try local_cache_directory.tmpFilePath(arena, fname);
3040+
3041+
try local_cache_directory.handle.makePath("tmp");
3042+
var outfile = try local_cache_directory.handle.createFile(new_name, .{});
3043+
defer outfile.close();
3044+
errdefer local_cache_directory.handle.deleteFile(new_name) catch {};
3045+
3046+
try outfile.writeFileAll(io.getStdIn(), .{});
3047+
break :blk new_name;
3048+
};
3049+
temp_stdin_file = new_file;
3050+
src.src_path = new_file;
30733051
}
30743052

30753053
if (build_options.have_llvm and emit_asm != .no) {

test/tests.zig

Lines changed: 41 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -781,42 +781,47 @@ pub fn addCliTests(b: *std.Build) *Step {
781781
// Test author was not able to figure out how to start a child process and
782782
// give an fd to it's stdin. fork/exec works, but we are limiting ourselves
783783
// to POSIX.
784-
if (builtin.os.tag != .windows) {
785-
const tmp_path = b.makeTempPath();
786-
var dir = std.fs.cwd().openDir(tmp_path, .{}) catch @panic("unhandled");
787-
dir.writeFile("truth.c", "int main() { return 42; }") catch @panic("unhandled");
788-
var infile = dir.openFile("truth.c", .{}) catch @panic("unhandled");
789-
790-
const outfile = std.fs.path.joinZ(
791-
b.allocator,
792-
&[_][]const u8{ tmp_path, "truth" },
793-
) catch @panic("unhandled");
794-
const pid_result = std.os.fork() catch @panic("unhandled");
795-
if (pid_result == 0) { // child
796-
std.os.dup2(infile.handle, std.os.STDIN_FILENO) catch @panic("unhandled");
797-
const argv = &[_:null]?[*:0]const u8{
798-
b.zig_exe, "cc",
799-
"-o", outfile,
800-
"-x", "c",
801-
"-",
802-
};
803-
const envp = &[_:null]?[*:0]const u8{
804-
std.fmt.allocPrintZ(b.allocator, "ZIG_GLOBAL_CACHE_DIR={s}", .{tmp_path}) catch @panic("unhandled"),
805-
};
806-
const err = std.os.execveZ(b.zig_exe, argv, envp);
807-
std.debug.print("execve error: {any}\n", .{err});
808-
std.os.exit(1);
809-
}
810-
811-
const res = std.os.waitpid(pid_result, 0);
812-
assert(0 == res.status);
813-
814-
// run the compiled executable and check if it's telling the truth.
815-
_ = exec(b.allocator, tmp_path, 42, &[_][]const u8{outfile}) catch @panic("unhandled");
816-
817-
const cleanup = b.addRemoveDirTree(tmp_path);
818-
step.dependOn(&cleanup.step);
819-
}
784+
//
785+
// TODO: the "zig cc <..." step should be a RunStep.create(...)
786+
// However, how do I create a command (RunStep) that invokes a command
787+
// with a specific file descriptor in the stdin?
788+
//if (builtin.os.tag != .windows) {
789+
// const tmp_path = b.makeTempPath();
790+
// var dir = std.fs.cwd().openDir(tmp_path, .{}) catch @panic("unhandled");
791+
// dir.writeFile("truth.c", "int main() { return 42; }") catch @panic("unhandled");
792+
// var infile = dir.openFile("truth.c", .{}) catch @panic("unhandled");
793+
794+
// const outfile = std.fs.path.joinZ(
795+
// b.allocator,
796+
// &[_][]const u8{ tmp_path, "truth" },
797+
// ) catch @panic("unhandled");
798+
799+
// const pid_result = std.os.fork() catch @panic("unhandled");
800+
// if (pid_result == 0) { // child
801+
// std.os.dup2(infile.handle, std.os.STDIN_FILENO) catch @panic("unhandled");
802+
// const argv = &[_:null]?[*:0]const u8{
803+
// b.zig_exe, "cc",
804+
// "-o", outfile,
805+
// "-x", "c",
806+
// "-",
807+
// };
808+
// const envp = &[_:null]?[*:0]const u8{
809+
// std.fmt.allocPrintZ(b.allocator, "ZIG_GLOBAL_CACHE_DIR={s}", .{tmp_path}) catch @panic("unhandled"),
810+
// };
811+
// const err = std.os.execveZ(b.zig_exe, argv, envp);
812+
// std.debug.print("execve error: {any}\n", .{err});
813+
// std.os.exit(1);
814+
// }
815+
816+
// const res = std.os.waitpid(pid_result, 0);
817+
// assert(0 == res.status);
818+
819+
// // run the compiled executable and check if it's telling the truth.
820+
// _ = exec(b.allocator, tmp_path, 42, &[_][]const u8{outfile}) catch @panic("unhandled");
821+
822+
// const cleanup = b.addRemoveDirTree(tmp_path);
823+
// step.dependOn(&cleanup.step);
824+
//}
820825

821826
{
822827
// Test `zig fmt`.

0 commit comments

Comments
 (0)