(no title)
ryanmjacobs | 1 year ago
Tempfile.create(anonymous: true) removes the created temporary file
immediately. So applications don’t need to remove the file.
[Feature #20497]
I use a similar pattern a lot: file = Tempfile.new.tap(&:unlink)
file << "... some really large data to pipe"
system("md5sum", in: file.tap(&:rewind))
It's a neat trick to leverage the filesystem for large amounts of data (e.g. "psql \copy" generation), without littering tempfiles everywhere. Once the last fd disappears, the filesystem releases the data; so you don't have to "trap" signals and add cleanup routines. (Hint: you can also use these unlinked-tempfiles for command output, e.g. huge grep output, etc.)On Linux systems, `open(..., O_TMPFILE)` is typically used, which provides additional safety. The created file is initially unnamed (no race condition between `open` and `unlink`).
When I needed safety, my non-portable solution was to use Ruby's syscall feature. (Btw, I love that you can do this.)
require "fcntl"
SYS_OPEN = 2
O_TMPFILE = 0x00410000
O_RDWR = Fcntl::O_RDWR
def tmpfile
mode = O_RDWR | O_TMPFILE
fd = syscall(SYS_OPEN, "/dev/shm", mode, 0644)
IO.for_fd(fd)
end
But... Another pleasant surprise from the PR (https://bugs.ruby-lang.org/issues/20497). Linux 3.11 has O_TMPFILE to create an unnamed file.
The current implementation uses it.
Excellent to see :)
Makes the PR even better!
15155|1 year ago