Files
bun.sh/src/tmp.zig
dave caruso 73a55cf075 windows: make more windows tests pass (#9370)
* run-eval.test.ts

* transpiler-cache.test.ts

* node net

* some open things

* a

* a

* yikes

* incredible

* run it back

* a

* this code is what i like to call, incorrect

* ok its all worng

* remove an assertion that is wrong again

* update test things and rebase

* performance test

* mark filesink with mkfifo as todo. see #8166

* hehe

* not done

* awa

* fs test pass

---------

Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
2024-03-22 23:40:45 -07:00

90 lines
3.2 KiB
Zig

const bun = @import("root").bun;
const std = @import("std");
const Environment = bun.Environment;
const O = std.os.O;
// O_TMPFILE doesn't seem to work very well.
const allow_tmpfile = false;
// To be used with files
// not folders!
pub const Tmpfile = struct {
destination_dir: bun.FileDescriptor = bun.invalid_fd,
tmpfilename: [:0]const u8 = "",
fd: bun.FileDescriptor = bun.invalid_fd,
using_tmpfile: bool = allow_tmpfile,
pub fn create(
destination_dir: bun.FileDescriptor,
tmpfilename: [:0]const u8,
) bun.JSC.Maybe(Tmpfile) {
const perm = 0o644;
var tmpfile = Tmpfile{
.destination_dir = destination_dir,
.tmpfilename = tmpfilename,
};
open: while (true) {
if (comptime allow_tmpfile) {
switch (bun.sys.openat(destination_dir, ".", O.WRONLY | O.TMPFILE | O.CLOEXEC, perm)) {
.result => |fd| {
tmpfile.fd = switch (bun.sys.makeLibUVOwnedFD(fd, .open, .close_on_fail)) {
.result => |owned_fd| owned_fd,
.err => |err| return .{ .err = err },
};
break :open;
},
.err => |err| {
switch (err.getErrno()) {
.INVAL, .OPNOTSUPP, .NOSYS => {
tmpfile.using_tmpfile = false;
},
else => return .{ .err = err },
}
},
}
}
tmpfile.fd = switch (bun.sys.openat(destination_dir, tmpfilename, O.CREAT | O.CLOEXEC | O.WRONLY, perm)) {
.result => |fd| switch (bun.sys.toLibUVOwnedFD(fd, .open, .close_on_fail)) {
.result => |owned_fd| owned_fd,
.err => |err| return .{ .err = err },
},
.err => |err| return .{ .err = err },
};
break :open;
}
return .{ .result = tmpfile };
}
pub fn finish(this: *Tmpfile, destname: [:0]const u8) !void {
if (comptime allow_tmpfile) {
if (this.using_tmpfile) {
var retry = true;
const basename: [:0]const u8 = @ptrCast(std.fs.path.basename(destname));
while (retry) {
const ret = bun.sys.linkatTmpfile(this.fd, this.destination_dir, basename);
switch (ret) {
.result => {
return;
},
.err => |err| {
if (err.getErrno() == .EXIST and retry) {
_ = bun.sys.unlinkat(this.destination_dir, basename);
retry = false;
continue;
} else {
try ret.unwrap();
return;
}
},
}
}
}
}
try bun.C.moveFileZWithHandle(this.fd, this.destination_dir, this.tmpfilename, this.destination_dir, destname);
}
};