6 ms·
I'm pleasantly surprised to see this improvement: Tempfile.create(anonymous: true) removes the created temporary file immediately. So applications don’t ne
by ryanmjacobs 2y ago
I'm pleasantly surprised to see this improvement:
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 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 2y agoThis is available in older Ruby versions by using the upstream `tempfile` gem version.