Skip to content

Commit df99c66

Browse files
motiejusandrewrk
authored andcommitted
read streams: remove probeFile
The API was strange. It is now clearer to have the logic in its own block.
1 parent 63a8baa commit df99c66

File tree

1 file changed

+37
-61
lines changed

1 file changed

+37
-61
lines changed

src/main.zig

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

664-
const FileType = union(enum) {
665-
regular,
666-
stream: struct {
667-
handle: std.os.fd_t,
668-
should_close_fd: bool,
669-
},
670-
};
671-
672-
// probeFile checks if the file is regular or a stream. If it is a stream, it
673-
// will return its file descriptor (open for reading) along with instruction
674-
// whether the caller should close the fd when done.
675-
fn probeFile(name: []const u8) !FileType {
676-
if (mem.eql(u8, name, "-"))
677-
return FileType{
678-
.stream = .{
679-
.handle = io.getStdIn().handle,
680-
.should_close_fd = false,
681-
},
682-
};
683-
684-
// all files are files or directories in windwos. So if it's not stdin,
685-
// it's a file.
686-
if (builtin.os.tag == .windows)
687-
return FileType.regular;
688-
689-
// we are on POSIX or wasm and need to determine if a given path
690-
// is a stream. We have 2 choices here:
691-
// 1. open + lseek. If lseek fails, it's a stream. Always 2 syscalls.
692-
// 2. fstat + optional open. If fstat tells us it's a file, we return
693-
// 'regular'. If it's not a file, we open and return the file descriptor.
694-
// One syscall if the file is a regular file, 2 syscalls if it is a stream.
695-
// Use the latter.
696-
697-
var stat_info = try std.os.fstatat(fs.cwd().fd, name, 0);
698-
if (stat_info.mode & std.os.S.IFMT == std.os.S.IFREG)
699-
return FileType.regular;
700-
701-
// Not a regular file. Open it and return a file descriptor.
702-
return FileType{
703-
.stream = .{
704-
.handle = try std.os.open(name, std.os.O.RDONLY, 0),
705-
.should_close_fd = true,
706-
},
707-
};
708-
}
709-
710664
// Read an open file descriptor to a new file in `dst_dir`. Return a file name
711665
// of the new file.
712666
fn copyToFile(
@@ -3111,30 +3065,52 @@ fn buildOutputType(
31113065
temp_files_for_comp.deinit();
31123066
}
31133067

3114-
// if a c_source_file is not a regular file, dump it to a tempdir.
3068+
// if a c_source_file is not a regular file, dump it to a tempdir
3069+
// and replace the src_name with the newly created file.
31153070
// translate-c works fine with streams; other actions don't.
31163071
if (arg_mode != .translate_c) {
3117-
for (c_source_files.items) |*src| {
3072+
c_src_loop: for (c_source_files.items) |*src| {
31183073
// optimization: if the file extension is known, assume it is
31193074
// a regular file and keep going. This is in the hot path.
31203075
// If we remove this check, all input files will get an extra
31213076
// syscall or two of overhead.
31223077
if (Compilation.classifyFileExt(src.src_path) != .unknown)
31233078
continue;
31243079

3125-
switch (try probeFile(src.src_path)) {
3126-
.regular => continue,
3127-
.stream => |o| {
3128-
if (o.should_close_fd)
3129-
std.os.close(o.handle);
3130-
if (src.ext == null)
3131-
fatal("-E or -x is required when reading from a non-regular file", .{});
3132-
3133-
const new_file = try copyToFile(arena, o.handle, local_cache_directory);
3134-
try temp_files_for_comp.append(new_file);
3135-
src.src_path = new_file;
3136-
},
3137-
}
3080+
// if the extension was not supplied or recognized, bail.
3081+
if (src.ext == null)
3082+
fatal("-E or -x is required when reading from a non-regular file", .{});
3083+
3084+
var close_fd = true;
3085+
const fd = blk: {
3086+
if (mem.eql(u8, src.src_path, "-")) {
3087+
close_fd = false;
3088+
break :blk io.getStdIn().handle;
3089+
}
3090+
3091+
// all things in a windows filesystem are files or directories.
3092+
// Therefore, if it is not stdin, it is a file.
3093+
if (builtin.os.tag == .windows)
3094+
continue :c_src_loop;
3095+
3096+
// On POSIX or wasm need to determine if a given path is a
3097+
// stream. 2 choices:
3098+
// 1. open + lseek. If lseek fails, it is a stream. Always 2
3099+
// syscalls.
3100+
// 2. fstat + optional open. If fstat says it's a file, return
3101+
// use it as such. If it is not a file, open and return the
3102+
// file descriptor. 1,5 syscall. Use this.
3103+
var stat_info = try std.os.fstatat(fs.cwd().fd, src.src_path, 0);
3104+
if (stat_info.mode & std.os.S.IFMT == std.os.S.IFREG)
3105+
continue :c_src_loop;
3106+
3107+
break :blk try std.os.open(src.src_path, std.os.O.RDONLY, 0);
3108+
};
3109+
defer if (close_fd) std.os.close(fd);
3110+
3111+
const new_file = try copyToFile(arena, fd, local_cache_directory);
3112+
try temp_files_for_comp.append(new_file);
3113+
src.src_path = new_file;
31383114
}
31393115
}
31403116

0 commit comments

Comments
 (0)