@@ -3043,19 +3043,36 @@ fn buildOutputType(
3043
3043
3044
3044
// "-" is stdin. Dump it to a real file.
3045
3045
const sep = fs .path .sep_str ;
3046
- const sub_path = try std .fmt .allocPrint (arena , "tmp" ++ sep ++ "{x}-stdin{s}" , .{
3046
+ const dump_path = try std .fmt .allocPrint (arena , "tmp" ++ sep ++ "{x}-dump -stdin{s}" , .{
3047
3047
std .crypto .random .int (u64 ), ext .canonicalName (target_info .target ),
3048
3048
});
3049
3049
try local_cache_directory .handle .makePath ("tmp" );
3050
- // Note that in one of the happy paths, execve() is used to switch
3051
- // to clang in which case any cleanup logic that exists for this
3052
- // temporary file will not run and this temp file will be leaked.
3053
- // Oh well. It's a minor punishment for using `-x c` which nobody
3054
- // should be doing. Therefore, we make no effort to clean up. Using
3055
- // ` -` for stdin as a source file always leaks a temp file.
3056
- var f = try local_cache_directory .handle .createFile (sub_path , .{});
3050
+
3051
+ // Note that in one of the happy paths, execve() is used to switch to
3052
+ // clang in which case any cleanup logic that exists for this temporary
3053
+ // file will not run and this temp file will be leaked. The filename
3054
+ // will be a hash of it's contents — so multiple invocations of `zig cc
3055
+ // -` will result in the same temp file.
3056
+ var f = try local_cache_directory .handle .createFile (dump_path , .{});
3057
3057
defer f .close ();
3058
- try f .writeFileAll (io .getStdIn (), .{});
3058
+
3059
+ // Re-using the hasher from Cache, since the functional requirements
3060
+ // for the hashing algorithm here and in the cache are the same.
3061
+ // We are providing our own cache key, because this file has nothing
3062
+ // to do with the cache manifest.
3063
+ var hasher = Cache .Hasher .init ("0123456789abcdef" );
3064
+ var w = io .multiWriter (.{ f .writer (), hasher .writer () });
3065
+ var fifo = std .fifo .LinearFifo (u8 , .{ .Static = 4096 }).init ();
3066
+ try fifo .pump (io .getStdIn ().reader (), w .writer ());
3067
+
3068
+ var bin_digest : Cache.BinDigest = undefined ;
3069
+ hasher .final (& bin_digest );
3070
+
3071
+ const sub_path = try std .fmt .allocPrint (arena , "tmp" ++ sep ++ "{s}-stdin{s}" , .{
3072
+ std .fmt .fmtSliceHexLower (& bin_digest ),
3073
+ ext .canonicalName (target_info .target ),
3074
+ });
3075
+ try local_cache_directory .handle .rename (dump_path , sub_path );
3059
3076
3060
3077
// Convert `sub_path` to be relative to current working directory.
3061
3078
src .src_path = try local_cache_directory .join (arena , &.{sub_path });
0 commit comments