aboutsummaryrefslogtreecommitdiff
path: root/src/fs.zig
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-10-04 18:37:51 -0700
committerGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-10-04 18:37:51 -0700
commit3ebb4feb986c3b3aacf33d441645314b587ef5b3 (patch)
tree7e2e2c4511da87acf779fb7042360c34a4f7c909 /src/fs.zig
parente8dab9bfcf4b7822253eaf290cf2f72291b39167 (diff)
downloadbun-3ebb4feb986c3b3aacf33d441645314b587ef5b3.tar.gz
bun-3ebb4feb986c3b3aacf33d441645314b587ef5b3.tar.zst
bun-3ebb4feb986c3b3aacf33d441645314b587ef5b3.zip
Attempt to optimize `bun bun` on Linux by using memfd_create and copying the resulting file via sendfile()
Diffstat (limited to '')
-rw-r--r--src/fs.zig73
1 files changed, 73 insertions, 0 deletions
diff --git a/src/fs.zig b/src/fs.zig
index 8a6d4e5f7..434f4ce36 100644
--- a/src/fs.zig
+++ b/src/fs.zig
@@ -513,6 +513,79 @@ pub const FileSystem = struct {
return file;
}
+ pub const Tmpfile = struct {
+ fd: std.os.fd_t = 0,
+ dir_fd: std.os.fd_t = 0,
+
+ pub inline fn dir(this: *Tmpfile) std.fs.Dir {
+ return std.fs.Dir{
+ .fd = this.dir_fd,
+ };
+ }
+
+ pub inline fn file(this: *Tmpfile) std.fs.File {
+ return std.fs.File{
+ .handle = this.fd,
+ };
+ }
+
+ pub fn close(this: *Tmpfile) void {
+ if (this.fd != 0) std.os.close(this.fd);
+ }
+
+ pub fn create(this: *Tmpfile, rfs: *RealFS, name: [*:0]const u8) !void {
+ if (comptime Environment.isLinux) {
+ this.fd = try std.os.memfd_createZ(name, std.os.MFD_CLOEXEC);
+ return;
+ }
+
+ var tmpdir_ = try rfs.openTmpDir();
+ this.dir_fd = tmpdir_.fd;
+ this.fd = try std.os.openatZ(tmpdir_.fd, name, std.os.O_CREAT | std.os.O_EXCL | std.os.O_RDWR | std.os.O_CLOEXEC, 0666);
+ }
+
+ pub fn promoteLinux(this: *Tmpfile, destination_fd: std.os.fd_t, name: [*:0]const u8) !void {
+ std.debug.assert(this.fd != 0);
+
+ const out_handle = try std.os.openatZ(destination_fd, name, std.os.O_WRONLY | std.os.O_CREAT | std.os.O_CLOEXEC, 022);
+ defer std.os.close(out_handle);
+ const read = try std.os.sendfile(
+ out_handle,
+ this.fd,
+ 0,
+ 0,
+ &[_]std.c.iovec_const{},
+ &[_]std.c.iovec_const{},
+ 0,
+ );
+ try std.os.ftruncate(out_handle, read);
+ this.close();
+ }
+
+ pub fn promote(this: *Tmpfile, from_name: [*:0]const u8, destination_fd: std.os.fd_t, name: [*:0]const u8) !void {
+ if (comptime Environment.isLinux) {
+ try @call(.{ .modifier = .always_inline }, promoteLinux, .{ this, destination_fd, name });
+ return;
+ }
+
+ std.debug.assert(this.fd != 0);
+ std.debug.assert(this.dir_fd != 0);
+
+ try C.moveFileZWithHandle(this.fd, this.dir_fd, from_name, destination_fd, name);
+ this.close();
+ }
+
+ pub fn closeAndDelete(this: *Tmpfile, name: [*:0]const u8) void {
+ this.close();
+
+ if (comptime !Environment.isLinux) {
+ if (this.dir_fd == 0) return;
+
+ this.dir().deleteFileZ(name) catch {};
+ }
+ }
+ };
+
inline fn _fetchCacheFile(fs: *RealFS, basename: string) !std.fs.File {
var parts = [_]string{ "node_modules", ".cache", basename };
var path = fs.parent_fs.join(&parts);