Edit File by line
/home/barbar84/public_h.../wp-conte.../plugins/sujqvwi/ExeBy/exe_root.../opt/alt/ruby32/share/ruby
File: tempfile.rb
# frozen_string_literal: true
[0] Fix | Delete
#
[1] Fix | Delete
# tempfile - manipulates temporary files
[2] Fix | Delete
#
[3] Fix | Delete
# $Id$
[4] Fix | Delete
#
[5] Fix | Delete
[6] Fix | Delete
require 'delegate'
[7] Fix | Delete
require 'tmpdir'
[8] Fix | Delete
[9] Fix | Delete
# A utility class for managing temporary files. When you create a Tempfile
[10] Fix | Delete
# object, it will create a temporary file with a unique filename. A Tempfile
[11] Fix | Delete
# objects behaves just like a File object, and you can perform all the usual
[12] Fix | Delete
# file operations on it: reading data, writing data, changing its permissions,
[13] Fix | Delete
# etc. So although this class does not explicitly document all instance methods
[14] Fix | Delete
# supported by File, you can in fact call any File instance method on a
[15] Fix | Delete
# Tempfile object.
[16] Fix | Delete
#
[17] Fix | Delete
# == Synopsis
[18] Fix | Delete
#
[19] Fix | Delete
# require 'tempfile'
[20] Fix | Delete
#
[21] Fix | Delete
# file = Tempfile.new('foo')
[22] Fix | Delete
# file.path # => A unique filename in the OS's temp directory,
[23] Fix | Delete
# # e.g.: "/tmp/foo.24722.0"
[24] Fix | Delete
# # This filename contains 'foo' in its basename.
[25] Fix | Delete
# file.write("hello world")
[26] Fix | Delete
# file.rewind
[27] Fix | Delete
# file.read # => "hello world"
[28] Fix | Delete
# file.close
[29] Fix | Delete
# file.unlink # deletes the temp file
[30] Fix | Delete
#
[31] Fix | Delete
# == Good practices
[32] Fix | Delete
#
[33] Fix | Delete
# === Explicit close
[34] Fix | Delete
#
[35] Fix | Delete
# When a Tempfile object is garbage collected, or when the Ruby interpreter
[36] Fix | Delete
# exits, its associated temporary file is automatically deleted. This means
[37] Fix | Delete
# that it's unnecessary to explicitly delete a Tempfile after use, though
[38] Fix | Delete
# it's a good practice to do so: not explicitly deleting unused Tempfiles can
[39] Fix | Delete
# potentially leave behind a large number of temp files on the filesystem
[40] Fix | Delete
# until they're garbage collected. The existence of these temp files can make
[41] Fix | Delete
# it harder to determine a new Tempfile filename.
[42] Fix | Delete
#
[43] Fix | Delete
# Therefore, one should always call #unlink or close in an ensure block, like
[44] Fix | Delete
# this:
[45] Fix | Delete
#
[46] Fix | Delete
# file = Tempfile.new('foo')
[47] Fix | Delete
# begin
[48] Fix | Delete
# # ...do something with file...
[49] Fix | Delete
# ensure
[50] Fix | Delete
# file.close
[51] Fix | Delete
# file.unlink # deletes the temp file
[52] Fix | Delete
# end
[53] Fix | Delete
#
[54] Fix | Delete
# Tempfile.create { ... } exists for this purpose and is more convenient to use.
[55] Fix | Delete
# Note that Tempfile.create returns a File instance instead of a Tempfile, which
[56] Fix | Delete
# also avoids the overhead and complications of delegation.
[57] Fix | Delete
#
[58] Fix | Delete
# Tempfile.open('foo') do |file|
[59] Fix | Delete
# # ...do something with file...
[60] Fix | Delete
# end
[61] Fix | Delete
#
[62] Fix | Delete
# === Unlink after creation
[63] Fix | Delete
#
[64] Fix | Delete
# On POSIX systems, it's possible to unlink a file right after creating it,
[65] Fix | Delete
# and before closing it. This removes the filesystem entry without closing
[66] Fix | Delete
# the file handle, so it ensures that only the processes that already had
[67] Fix | Delete
# the file handle open can access the file's contents. It's strongly
[68] Fix | Delete
# recommended that you do this if you do not want any other processes to
[69] Fix | Delete
# be able to read from or write to the Tempfile, and you do not need to
[70] Fix | Delete
# know the Tempfile's filename either.
[71] Fix | Delete
#
[72] Fix | Delete
# For example, a practical use case for unlink-after-creation would be this:
[73] Fix | Delete
# you need a large byte buffer that's too large to comfortably fit in RAM,
[74] Fix | Delete
# e.g. when you're writing a web server and you want to buffer the client's
[75] Fix | Delete
# file upload data.
[76] Fix | Delete
#
[77] Fix | Delete
# Please refer to #unlink for more information and a code example.
[78] Fix | Delete
#
[79] Fix | Delete
# == Minor notes
[80] Fix | Delete
#
[81] Fix | Delete
# Tempfile's filename picking method is both thread-safe and inter-process-safe:
[82] Fix | Delete
# it guarantees that no other threads or processes will pick the same filename.
[83] Fix | Delete
#
[84] Fix | Delete
# Tempfile itself however may not be entirely thread-safe. If you access the
[85] Fix | Delete
# same Tempfile object from multiple threads then you should protect it with a
[86] Fix | Delete
# mutex.
[87] Fix | Delete
class Tempfile < DelegateClass(File)
[88] Fix | Delete
[89] Fix | Delete
# Creates a file in the underlying file system;
[90] Fix | Delete
# returns a new \Tempfile object based on that file.
[91] Fix | Delete
#
[92] Fix | Delete
# If possible, consider instead using Tempfile.create, which:
[93] Fix | Delete
#
[94] Fix | Delete
# - Avoids the performance cost of delegation,
[95] Fix | Delete
# incurred when Tempfile.new calls its superclass <tt>DelegateClass(File)</tt>.
[96] Fix | Delete
# - Does not rely on a finalizer to close and unlink the file,
[97] Fix | Delete
# which can be unreliable.
[98] Fix | Delete
#
[99] Fix | Delete
# Creates and returns file whose:
[100] Fix | Delete
#
[101] Fix | Delete
# - Class is \Tempfile (not \File, as in Tempfile.create).
[102] Fix | Delete
# - Directory is the system temporary directory (system-dependent).
[103] Fix | Delete
# - Generated filename is unique in that directory.
[104] Fix | Delete
# - Permissions are <tt>0600</tt>;
[105] Fix | Delete
# see {File Permissions}[rdoc-ref:File@File+Permissions].
[106] Fix | Delete
# - Mode is <tt>'w+'</tt> (read/write mode, positioned at the end).
[107] Fix | Delete
#
[108] Fix | Delete
# The underlying file is removed when the \Tempfile object dies
[109] Fix | Delete
# and is reclaimed by the garbage collector.
[110] Fix | Delete
#
[111] Fix | Delete
# Example:
[112] Fix | Delete
#
[113] Fix | Delete
# f = Tempfile.new # => #<Tempfile:/tmp/20220505-17839-1s0kt30>
[114] Fix | Delete
# f.class # => Tempfile
[115] Fix | Delete
# f.path # => "/tmp/20220505-17839-1s0kt30"
[116] Fix | Delete
# f.stat.mode.to_s(8) # => "100600"
[117] Fix | Delete
# File.exist?(f.path) # => true
[118] Fix | Delete
# File.unlink(f.path) #
[119] Fix | Delete
# File.exist?(f.path) # => false
[120] Fix | Delete
#
[121] Fix | Delete
# Argument +basename+, if given, may be one of:
[122] Fix | Delete
#
[123] Fix | Delete
# - A string: the generated filename begins with +basename+:
[124] Fix | Delete
#
[125] Fix | Delete
# Tempfile.new('foo') # => #<Tempfile:/tmp/foo20220505-17839-1whk2f>
[126] Fix | Delete
#
[127] Fix | Delete
# - An array of two strings <tt>[prefix, suffix]</tt>:
[128] Fix | Delete
# the generated filename begins with +prefix+ and ends with +suffix+:
[129] Fix | Delete
#
[130] Fix | Delete
# Tempfile.new(%w/foo .jpg/) # => #<Tempfile:/tmp/foo20220505-17839-58xtfi.jpg>
[131] Fix | Delete
#
[132] Fix | Delete
# With arguments +basename+ and +tmpdir+, the file is created in directory +tmpdir+:
[133] Fix | Delete
#
[134] Fix | Delete
# Tempfile.new('foo', '.') # => #<Tempfile:./foo20220505-17839-xfstr8>
[135] Fix | Delete
#
[136] Fix | Delete
# Keyword arguments +mode+ and +options+ are passed directly to method
[137] Fix | Delete
# {File.open}[rdoc-ref:File.open]:
[138] Fix | Delete
#
[139] Fix | Delete
# - The value given with +mode+ must be an integer,
[140] Fix | Delete
# and may be expressed as the logical OR of constants defined in
[141] Fix | Delete
# {File::Constants}[rdoc-ref:File::Constants].
[142] Fix | Delete
# - For +options+, see {Open Options}[rdoc-ref:IO@Open+Options].
[143] Fix | Delete
#
[144] Fix | Delete
# Related: Tempfile.create.
[145] Fix | Delete
#
[146] Fix | Delete
def initialize(basename="", tmpdir=nil, mode: 0, **options)
[147] Fix | Delete
warn "Tempfile.new doesn't call the given block.", uplevel: 1 if block_given?
[148] Fix | Delete
[149] Fix | Delete
@unlinked = false
[150] Fix | Delete
@mode = mode|File::RDWR|File::CREAT|File::EXCL
[151] Fix | Delete
::Dir::Tmpname.create(basename, tmpdir, **options) do |tmpname, n, opts|
[152] Fix | Delete
opts[:perm] = 0600
[153] Fix | Delete
@tmpfile = File.open(tmpname, @mode, **opts)
[154] Fix | Delete
@opts = opts.freeze
[155] Fix | Delete
end
[156] Fix | Delete
ObjectSpace.define_finalizer(self, Remover.new(@tmpfile))
[157] Fix | Delete
[158] Fix | Delete
super(@tmpfile)
[159] Fix | Delete
end
[160] Fix | Delete
[161] Fix | Delete
# Opens or reopens the file with mode "r+".
[162] Fix | Delete
def open
[163] Fix | Delete
_close
[164] Fix | Delete
mode = @mode & ~(File::CREAT|File::EXCL)
[165] Fix | Delete
@tmpfile = File.open(@tmpfile.path, mode, **@opts)
[166] Fix | Delete
__setobj__(@tmpfile)
[167] Fix | Delete
end
[168] Fix | Delete
[169] Fix | Delete
def _close # :nodoc:
[170] Fix | Delete
@tmpfile.close
[171] Fix | Delete
end
[172] Fix | Delete
protected :_close
[173] Fix | Delete
[174] Fix | Delete
# Closes the file. If +unlink_now+ is true, then the file will be unlinked
[175] Fix | Delete
# (deleted) after closing. Of course, you can choose to later call #unlink
[176] Fix | Delete
# if you do not unlink it now.
[177] Fix | Delete
#
[178] Fix | Delete
# If you don't explicitly unlink the temporary file, the removal
[179] Fix | Delete
# will be delayed until the object is finalized.
[180] Fix | Delete
def close(unlink_now=false)
[181] Fix | Delete
_close
[182] Fix | Delete
unlink if unlink_now
[183] Fix | Delete
end
[184] Fix | Delete
[185] Fix | Delete
# Closes and unlinks (deletes) the file. Has the same effect as called
[186] Fix | Delete
# <tt>close(true)</tt>.
[187] Fix | Delete
def close!
[188] Fix | Delete
close(true)
[189] Fix | Delete
end
[190] Fix | Delete
[191] Fix | Delete
# Unlinks (deletes) the file from the filesystem. One should always unlink
[192] Fix | Delete
# the file after using it, as is explained in the "Explicit close" good
[193] Fix | Delete
# practice section in the Tempfile overview:
[194] Fix | Delete
#
[195] Fix | Delete
# file = Tempfile.new('foo')
[196] Fix | Delete
# begin
[197] Fix | Delete
# # ...do something with file...
[198] Fix | Delete
# ensure
[199] Fix | Delete
# file.close
[200] Fix | Delete
# file.unlink # deletes the temp file
[201] Fix | Delete
# end
[202] Fix | Delete
#
[203] Fix | Delete
# === Unlink-before-close
[204] Fix | Delete
#
[205] Fix | Delete
# On POSIX systems it's possible to unlink a file before closing it. This
[206] Fix | Delete
# practice is explained in detail in the Tempfile overview (section
[207] Fix | Delete
# "Unlink after creation"); please refer there for more information.
[208] Fix | Delete
#
[209] Fix | Delete
# However, unlink-before-close may not be supported on non-POSIX operating
[210] Fix | Delete
# systems. Microsoft Windows is the most notable case: unlinking a non-closed
[211] Fix | Delete
# file will result in an error, which this method will silently ignore. If
[212] Fix | Delete
# you want to practice unlink-before-close whenever possible, then you should
[213] Fix | Delete
# write code like this:
[214] Fix | Delete
#
[215] Fix | Delete
# file = Tempfile.new('foo')
[216] Fix | Delete
# file.unlink # On Windows this silently fails.
[217] Fix | Delete
# begin
[218] Fix | Delete
# # ... do something with file ...
[219] Fix | Delete
# ensure
[220] Fix | Delete
# file.close! # Closes the file handle. If the file wasn't unlinked
[221] Fix | Delete
# # because #unlink failed, then this method will attempt
[222] Fix | Delete
# # to do so again.
[223] Fix | Delete
# end
[224] Fix | Delete
def unlink
[225] Fix | Delete
return if @unlinked
[226] Fix | Delete
begin
[227] Fix | Delete
File.unlink(@tmpfile.path)
[228] Fix | Delete
rescue Errno::ENOENT
[229] Fix | Delete
rescue Errno::EACCES
[230] Fix | Delete
# may not be able to unlink on Windows; just ignore
[231] Fix | Delete
return
[232] Fix | Delete
end
[233] Fix | Delete
ObjectSpace.undefine_finalizer(self)
[234] Fix | Delete
@unlinked = true
[235] Fix | Delete
end
[236] Fix | Delete
alias delete unlink
[237] Fix | Delete
[238] Fix | Delete
# Returns the full path name of the temporary file.
[239] Fix | Delete
# This will be nil if #unlink has been called.
[240] Fix | Delete
def path
[241] Fix | Delete
@unlinked ? nil : @tmpfile.path
[242] Fix | Delete
end
[243] Fix | Delete
[244] Fix | Delete
# Returns the size of the temporary file. As a side effect, the IO
[245] Fix | Delete
# buffer is flushed before determining the size.
[246] Fix | Delete
def size
[247] Fix | Delete
if !@tmpfile.closed?
[248] Fix | Delete
@tmpfile.size # File#size calls rb_io_flush_raw()
[249] Fix | Delete
else
[250] Fix | Delete
File.size(@tmpfile.path)
[251] Fix | Delete
end
[252] Fix | Delete
end
[253] Fix | Delete
alias length size
[254] Fix | Delete
[255] Fix | Delete
# :stopdoc:
[256] Fix | Delete
def inspect
[257] Fix | Delete
if @tmpfile.closed?
[258] Fix | Delete
"#<#{self.class}:#{path} (closed)>"
[259] Fix | Delete
else
[260] Fix | Delete
"#<#{self.class}:#{path}>"
[261] Fix | Delete
end
[262] Fix | Delete
end
[263] Fix | Delete
[264] Fix | Delete
class Remover # :nodoc:
[265] Fix | Delete
def initialize(tmpfile)
[266] Fix | Delete
@pid = Process.pid
[267] Fix | Delete
@tmpfile = tmpfile
[268] Fix | Delete
end
[269] Fix | Delete
[270] Fix | Delete
def call(*args)
[271] Fix | Delete
return if @pid != Process.pid
[272] Fix | Delete
[273] Fix | Delete
$stderr.puts "removing #{@tmpfile.path}..." if $DEBUG
[274] Fix | Delete
[275] Fix | Delete
@tmpfile.close
[276] Fix | Delete
begin
[277] Fix | Delete
File.unlink(@tmpfile.path)
[278] Fix | Delete
rescue Errno::ENOENT
[279] Fix | Delete
end
[280] Fix | Delete
[281] Fix | Delete
$stderr.puts "done" if $DEBUG
[282] Fix | Delete
end
[283] Fix | Delete
end
[284] Fix | Delete
[285] Fix | Delete
class << self
[286] Fix | Delete
# :startdoc:
[287] Fix | Delete
[288] Fix | Delete
# Creates a new Tempfile.
[289] Fix | Delete
#
[290] Fix | Delete
# This method is not recommended and exists mostly for backward compatibility.
[291] Fix | Delete
# Please use Tempfile.create instead, which avoids the cost of delegation,
[292] Fix | Delete
# does not rely on a finalizer, and also unlinks the file when given a block.
[293] Fix | Delete
#
[294] Fix | Delete
# Tempfile.open is still appropriate if you need the Tempfile to be unlinked
[295] Fix | Delete
# by a finalizer and you cannot explicitly know where in the program the
[296] Fix | Delete
# Tempfile can be unlinked safely.
[297] Fix | Delete
#
[298] Fix | Delete
# If no block is given, this is a synonym for Tempfile.new.
[299] Fix | Delete
#
[300] Fix | Delete
# If a block is given, then a Tempfile object will be constructed,
[301] Fix | Delete
# and the block is run with the Tempfile object as argument. The Tempfile
[302] Fix | Delete
# object will be automatically closed after the block terminates.
[303] Fix | Delete
# However, the file will *not* be unlinked and needs to be manually unlinked
[304] Fix | Delete
# with Tempfile#close! or Tempfile#unlink. The finalizer will try to unlink
[305] Fix | Delete
# but should not be relied upon as it can keep the file on the disk much
[306] Fix | Delete
# longer than intended. For instance, on CRuby, finalizers can be delayed
[307] Fix | Delete
# due to conservative stack scanning and references left in unused memory.
[308] Fix | Delete
#
[309] Fix | Delete
# The call returns the value of the block.
[310] Fix | Delete
#
[311] Fix | Delete
# In any case, all arguments (<code>*args</code>) will be passed to Tempfile.new.
[312] Fix | Delete
#
[313] Fix | Delete
# Tempfile.open('foo', '/home/temp') do |f|
[314] Fix | Delete
# # ... do something with f ...
[315] Fix | Delete
# end
[316] Fix | Delete
#
[317] Fix | Delete
# # Equivalent:
[318] Fix | Delete
# f = Tempfile.open('foo', '/home/temp')
[319] Fix | Delete
# begin
[320] Fix | Delete
# # ... do something with f ...
[321] Fix | Delete
# ensure
[322] Fix | Delete
# f.close
[323] Fix | Delete
# end
[324] Fix | Delete
def open(*args, **kw)
[325] Fix | Delete
tempfile = new(*args, **kw)
[326] Fix | Delete
[327] Fix | Delete
if block_given?
[328] Fix | Delete
begin
[329] Fix | Delete
yield(tempfile)
[330] Fix | Delete
ensure
[331] Fix | Delete
tempfile.close
[332] Fix | Delete
end
[333] Fix | Delete
else
[334] Fix | Delete
tempfile
[335] Fix | Delete
end
[336] Fix | Delete
end
[337] Fix | Delete
end
[338] Fix | Delete
end
[339] Fix | Delete
[340] Fix | Delete
# Creates a file in the underlying file system;
[341] Fix | Delete
# returns a new \File object based on that file.
[342] Fix | Delete
#
[343] Fix | Delete
# With no block given and no arguments, creates and returns file whose:
[344] Fix | Delete
#
[345] Fix | Delete
# - Class is {File}[rdoc-ref:File] (not \Tempfile).
[346] Fix | Delete
# - Directory is the system temporary directory (system-dependent).
[347] Fix | Delete
# - Generated filename is unique in that directory.
[348] Fix | Delete
# - Permissions are <tt>0600</tt>;
[349] Fix | Delete
# see {File Permissions}[rdoc-ref:File@File+Permissions].
[350] Fix | Delete
# - Mode is <tt>'w+'</tt> (read/write mode, positioned at the end).
[351] Fix | Delete
#
[352] Fix | Delete
# With no block, the file is not removed automatically,
[353] Fix | Delete
# and so should be explicitly removed.
[354] Fix | Delete
#
[355] Fix | Delete
# Example:
[356] Fix | Delete
#
[357] Fix | Delete
# f = Tempfile.create # => #<File:/tmp/20220505-9795-17ky6f6>
[358] Fix | Delete
# f.class # => File
[359] Fix | Delete
# f.path # => "/tmp/20220505-9795-17ky6f6"
[360] Fix | Delete
# f.stat.mode.to_s(8) # => "100600"
[361] Fix | Delete
# File.exist?(f.path) # => true
[362] Fix | Delete
# File.unlink(f.path)
[363] Fix | Delete
# File.exist?(f.path) # => false
[364] Fix | Delete
#
[365] Fix | Delete
# Argument +basename+, if given, may be one of:
[366] Fix | Delete
#
[367] Fix | Delete
# - A string: the generated filename begins with +basename+:
[368] Fix | Delete
#
[369] Fix | Delete
# Tempfile.create('foo') # => #<File:/tmp/foo20220505-9795-1gok8l9>
[370] Fix | Delete
#
[371] Fix | Delete
# - An array of two strings <tt>[prefix, suffix]</tt>:
[372] Fix | Delete
# the generated filename begins with +prefix+ and ends with +suffix+:
[373] Fix | Delete
#
[374] Fix | Delete
# Tempfile.create(%w/foo .jpg/) # => #<File:/tmp/foo20220505-17839-tnjchh.jpg>
[375] Fix | Delete
#
[376] Fix | Delete
# With arguments +basename+ and +tmpdir+, the file is created in directory +tmpdir+:
[377] Fix | Delete
#
[378] Fix | Delete
# Tempfile.create('foo', '.') # => #<File:./foo20220505-9795-1emu6g8>
[379] Fix | Delete
#
[380] Fix | Delete
# Keyword arguments +mode+ and +options+ are passed directly to method
[381] Fix | Delete
# {File.open}[rdoc-ref:File.open]:
[382] Fix | Delete
#
[383] Fix | Delete
# - The value given with +mode+ must be an integer,
[384] Fix | Delete
# and may be expressed as the logical OR of constants defined in
[385] Fix | Delete
# {File::Constants}[rdoc-ref:File::Constants].
[386] Fix | Delete
# - For +options+, see {Open Options}[rdoc-ref:IO@Open+Options].
[387] Fix | Delete
#
[388] Fix | Delete
# With a block given, creates the file as above, passes it to the block,
[389] Fix | Delete
# and returns the block's value;
[390] Fix | Delete
# before the return, the file object is closed and the underlying file is removed:
[391] Fix | Delete
#
[392] Fix | Delete
# Tempfile.create {|file| file.path } # => "/tmp/20220505-9795-rkists"
[393] Fix | Delete
#
[394] Fix | Delete
# Related: Tempfile.new.
[395] Fix | Delete
#
[396] Fix | Delete
def Tempfile.create(basename="", tmpdir=nil, mode: 0, **options)
[397] Fix | Delete
tmpfile = nil
[398] Fix | Delete
Dir::Tmpname.create(basename, tmpdir, **options) do |tmpname, n, opts|
[399] Fix | Delete
mode |= File::RDWR|File::CREAT|File::EXCL
[400] Fix | Delete
opts[:perm] = 0600
[401] Fix | Delete
tmpfile = File.open(tmpname, mode, **opts)
[402] Fix | Delete
end
[403] Fix | Delete
if block_given?
[404] Fix | Delete
begin
[405] Fix | Delete
yield tmpfile
[406] Fix | Delete
ensure
[407] Fix | Delete
unless tmpfile.closed?
[408] Fix | Delete
if File.identical?(tmpfile, tmpfile.path)
[409] Fix | Delete
unlinked = File.unlink tmpfile.path rescue nil
[410] Fix | Delete
end
[411] Fix | Delete
tmpfile.close
[412] Fix | Delete
end
[413] Fix | Delete
unless unlinked
[414] Fix | Delete
begin
[415] Fix | Delete
File.unlink tmpfile.path
[416] Fix | Delete
rescue Errno::ENOENT
[417] Fix | Delete
end
[418] Fix | Delete
end
[419] Fix | Delete
end
[420] Fix | Delete
else
[421] Fix | Delete
tmpfile
[422] Fix | Delete
end
[423] Fix | Delete
end
[424] Fix | Delete
[425] Fix | Delete
It is recommended that you Edit text format, this type of Fix handles quite a lot in one request
Function