@@ -661,52 +661,6 @@ fn optionalStringEnvVar(arena: Allocator, name: []const u8) !?[]const u8 {
661
661
}
662
662
}
663
663
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
-
710
664
// Read an open file descriptor to a new file in `dst_dir`. Return a file name
711
665
// of the new file.
712
666
fn copyToFile (
@@ -3111,30 +3065,52 @@ fn buildOutputType(
3111
3065
temp_files_for_comp .deinit ();
3112
3066
}
3113
3067
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.
3115
3070
// translate-c works fine with streams; other actions don't.
3116
3071
if (arg_mode != .translate_c ) {
3117
- for (c_source_files .items ) | * src | {
3072
+ c_src_loop : for (c_source_files .items ) | * src | {
3118
3073
// optimization: if the file extension is known, assume it is
3119
3074
// a regular file and keep going. This is in the hot path.
3120
3075
// If we remove this check, all input files will get an extra
3121
3076
// syscall or two of overhead.
3122
3077
if (Compilation .classifyFileExt (src .src_path ) != .unknown )
3123
3078
continue ;
3124
3079
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 ;
3138
3114
}
3139
3115
}
3140
3116
0 commit comments