Bug #8816
closedTempfile.new may return the same name for parallel calls
Description
Two simultaneous call to Tempfile.new may return the same name. This may lead
to race conditions.
There some examples of such races (unix socket can't be unlinked because it was
unlinked by another test case):
https://buildd.debian.org/status/fetch.php?pkg=ruby-kgio&arch=ia64&ver=2.8.0-1&stamp=1376819434
https://buildd.debian.org/status/fetch.php?pkg=ruby-kgio&arch=kfreebsd-i386&ver=2.8.0-1&stamp=1376820662
Updated by akr (Akira Tanaka) over 11 years ago
- Status changed from Open to Third Party's Issue
Tempfile.new creates a normal file, not unix socket.
So, your report is questionable.
Note that Tempfile uses O_EXCL to exclusive file creation.
If it doesn't work, it is a problem of kernel.
I checked kgio.
It seems the temporary file created by Tempfile.new is removed and
unix socket is created the name.
http://bogomips.org/kgio.git/tree/test/test_unix_connect.rb :
class TestKgioUnixConnect < Test::Unit::TestCase
def setup
tmp = Tempfile.new('kgio_unix')
@path = tmp.path
File.unlink(@path)
tmp.close rescue nil
@srv = Kgio::UNIXServer.new(@path)
@addr = Socket.pack_sockaddr_un(@path)
end
The race condition should be solved by application.
Because another process may creates the file between unlink and unix socket creation.
Tempfile cannot do anything between them because Tempfile methods are not running at that time.
Updated by normalperson (Eric Wong) over 11 years ago
"akr (Akira Tanaka)" akr@fsij.org wrote:
http://bogomips.org/kgio.git/tree/test/test_unix_connect.rb :
class TestKgioUnixConnect < Test::Unit::TestCase
def setup tmp = Tempfile.new('kgio_unix') @path = tmp.path File.unlink(@path) tmp.close rescue nil @srv = Kgio::UNIXServer.new(@path) @addr = Socket.pack_sockaddr_un(@path) end
The race condition should be solved by application.
Agreed (kgio maintainer here).
Hleb: can you send me a patch to retry on bind failure?
I'm a little surprised it happens since $$ is in the Tempfile name and
the tests are not multi-threaded (but optionally multi-process).
Because another process may creates the file between unlink and unix
socket creation.
Tempfile cannot do anything between them because Tempfile methods are
not running at that time.
Right. I do this often in test cases, but I'm lazy and have never hit
a problem even though I know it's there :x
Updated by nobu (Nobuyoshi Nakada) over 11 years ago
Tempfile.create may help you to create unique file name, but it's your task to guarantee that it doesn't conflict.