mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	* lib/pp.rb: Ditto. * lib/prettyprint.rb: Ditto. * lib/resolv.rb: Ditto. * lib/securerandom.rb: Ditto. * lib/tmpdir.rb: Ditto. * lib/unicode_normalize/tables.rb: Ditto. * test/net/ftp/test_buffered_socket.rb: Ditto. * test/net/ftp/test_mlsx_entry.rb: Ditto. * test/open-uri/test_open-uri.rb: Ditto. * test/open-uri/test_ssl.rb: Ditto. * test/pathname/test_pathname.rb: Ditto. * test/test_pp.rb: Ditto. * test/test_prettyprint.rb: Ditto. * tool/transcode-tblgen.rb: Ditto. * ext/pathname/lib/pathname.rb: Ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52526 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
		
			
				
	
	
		
			140 lines
		
	
	
	
		
			4 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			140 lines
		
	
	
	
		
			4 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
# frozen_string_literal: true
 | 
						|
#
 | 
						|
# tmpdir - retrieve temporary directory path
 | 
						|
#
 | 
						|
# $Id$
 | 
						|
#
 | 
						|
 | 
						|
require 'fileutils'
 | 
						|
begin
 | 
						|
  require 'etc.so'
 | 
						|
rescue LoadError # rescue LoadError for miniruby
 | 
						|
end
 | 
						|
 | 
						|
class Dir
 | 
						|
 | 
						|
  @@systmpdir ||= defined?(Etc.systmpdir) ? Etc.systmpdir : '/tmp'
 | 
						|
 | 
						|
  ##
 | 
						|
  # Returns the operating system's temporary file path.
 | 
						|
 | 
						|
  def self.tmpdir
 | 
						|
    if $SAFE > 0
 | 
						|
      @@systmpdir.dup
 | 
						|
    else
 | 
						|
      tmp = nil
 | 
						|
      [ENV['TMPDIR'], ENV['TMP'], ENV['TEMP'], @@systmpdir, '/tmp', '.'].each do |dir|
 | 
						|
        next if !dir
 | 
						|
        dir = File.expand_path(dir)
 | 
						|
        if stat = File.stat(dir) and stat.directory? and stat.writable? and
 | 
						|
            (!stat.world_writable? or stat.sticky?)
 | 
						|
          tmp = dir
 | 
						|
          break
 | 
						|
        end rescue nil
 | 
						|
      end
 | 
						|
      raise ArgumentError, "could not find a temporary directory" unless tmp
 | 
						|
      tmp
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  # Dir.mktmpdir creates a temporary directory.
 | 
						|
  #
 | 
						|
  # The directory is created with 0700 permission.
 | 
						|
  # Application should not change the permission to make the temporary directory accessible from other users.
 | 
						|
  #
 | 
						|
  # The prefix and suffix of the name of the directory is specified by
 | 
						|
  # the optional first argument, <i>prefix_suffix</i>.
 | 
						|
  # - If it is not specified or nil, "d" is used as the prefix and no suffix is used.
 | 
						|
  # - If it is a string, it is used as the prefix and no suffix is used.
 | 
						|
  # - If it is an array, first element is used as the prefix and second element is used as a suffix.
 | 
						|
  #
 | 
						|
  #  Dir.mktmpdir {|dir| dir is ".../d..." }
 | 
						|
  #  Dir.mktmpdir("foo") {|dir| dir is ".../foo..." }
 | 
						|
  #  Dir.mktmpdir(["foo", "bar"]) {|dir| dir is ".../foo...bar" }
 | 
						|
  #
 | 
						|
  # The directory is created under Dir.tmpdir or
 | 
						|
  # the optional second argument <i>tmpdir</i> if non-nil value is given.
 | 
						|
  #
 | 
						|
  #  Dir.mktmpdir {|dir| dir is "#{Dir.tmpdir}/d..." }
 | 
						|
  #  Dir.mktmpdir(nil, "/var/tmp") {|dir| dir is "/var/tmp/d..." }
 | 
						|
  #
 | 
						|
  # If a block is given,
 | 
						|
  # it is yielded with the path of the directory.
 | 
						|
  # The directory and its contents are removed
 | 
						|
  # using FileUtils.remove_entry before Dir.mktmpdir returns.
 | 
						|
  # The value of the block is returned.
 | 
						|
  #
 | 
						|
  #  Dir.mktmpdir {|dir|
 | 
						|
  #    # use the directory...
 | 
						|
  #    open("#{dir}/foo", "w") { ... }
 | 
						|
  #  }
 | 
						|
  #
 | 
						|
  # If a block is not given,
 | 
						|
  # The path of the directory is returned.
 | 
						|
  # In this case, Dir.mktmpdir doesn't remove the directory.
 | 
						|
  #
 | 
						|
  #  dir = Dir.mktmpdir
 | 
						|
  #  begin
 | 
						|
  #    # use the directory...
 | 
						|
  #    open("#{dir}/foo", "w") { ... }
 | 
						|
  #  ensure
 | 
						|
  #    # remove the directory.
 | 
						|
  #    FileUtils.remove_entry dir
 | 
						|
  #  end
 | 
						|
  #
 | 
						|
  def Dir.mktmpdir(prefix_suffix=nil, *rest)
 | 
						|
    path = Tmpname.create(prefix_suffix || "d", *rest) {|n| mkdir(n, 0700)}
 | 
						|
    if block_given?
 | 
						|
      begin
 | 
						|
        yield path
 | 
						|
      ensure
 | 
						|
        stat = File.stat(File.dirname(path))
 | 
						|
        if stat.world_writable? and !stat.sticky?
 | 
						|
          raise ArgumentError, "parent directory is world writable but not sticky"
 | 
						|
        end
 | 
						|
        FileUtils.remove_entry path
 | 
						|
      end
 | 
						|
    else
 | 
						|
      path
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  module Tmpname # :nodoc:
 | 
						|
    module_function
 | 
						|
 | 
						|
    def tmpdir
 | 
						|
      Dir.tmpdir
 | 
						|
    end
 | 
						|
 | 
						|
    def make_tmpname((prefix, suffix), n)
 | 
						|
      prefix = (String.try_convert(prefix) or
 | 
						|
                raise ArgumentError, "unexpected prefix: #{prefix.inspect}")
 | 
						|
      suffix &&= (String.try_convert(suffix) or
 | 
						|
                  raise ArgumentError, "unexpected suffix: #{suffix.inspect}")
 | 
						|
      t = Time.now.strftime("%Y%m%d")
 | 
						|
      path = "#{prefix}#{t}-#{$$}-#{rand(0x100000000).to_s(36)}".dup
 | 
						|
      path << "-#{n}" if n
 | 
						|
      path << suffix if suffix
 | 
						|
      path
 | 
						|
    end
 | 
						|
 | 
						|
    def create(basename, tmpdir=nil, max_try: nil, **opts)
 | 
						|
      if $SAFE > 0 and tmpdir.tainted?
 | 
						|
        tmpdir = '/tmp'
 | 
						|
      else
 | 
						|
        tmpdir ||= tmpdir()
 | 
						|
      end
 | 
						|
      n = nil
 | 
						|
      begin
 | 
						|
        path = File.join(tmpdir, make_tmpname(basename, n))
 | 
						|
        yield(path, n, opts)
 | 
						|
      rescue Errno::EEXIST
 | 
						|
        n ||= 0
 | 
						|
        n += 1
 | 
						|
        retry if !max_try or n < max_try
 | 
						|
        raise "cannot generate temporary name using `#{basename}' under `#{tmpdir}'"
 | 
						|
      end
 | 
						|
      path
 | 
						|
    end
 | 
						|
  end
 | 
						|
end
 |