Module: FileHelper

Extended by:
FileHelper
Included in:
FileHelper
Defined in:
lib/filewatch/helper.rb

Instance Method Summary collapse

Instance Method Details

#device?(file_name) ⇒ Boolean

Returns:

  • (Boolean)


46
47
48
# File 'lib/filewatch/helper.rb', line 46

def device?(file_name)
  File.chardev?(file_name) || File.blockdev?(file_name)
end

#probe_stat_in(dir) ⇒ Object

Private utility method.



51
52
53
54
55
56
57
58
59
60
# File 'lib/filewatch/helper.rb', line 51

def probe_stat_in(dir) #:nodoc:
  basename = rand_filename(".permissions_check")
  file_name = File.join(dir, basename)
  FileUtils.touch(file_name)
  File.stat(file_name)
rescue
  # ...
ensure
  FileUtils.rm_f(file_name) if File.exist?(file_name)
end

#rand_filename(prefix) ⇒ Object



62
63
64
# File 'lib/filewatch/helper.rb', line 62

def rand_filename(prefix)
  [ prefix, Thread.current.object_id, Process.pid, rand(1000000) ].join('.')
end

#write_atomically(file_name) ⇒ Object

Write to a file atomically. Useful for situations where you don’t want other processes or threads to see half-written files.

File.write_atomically('important.file') do |file|
  file.write('hello')
end


15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/filewatch/helper.rb', line 15

def write_atomically(file_name)

  if File.exist?(file_name)
    # Get original file permissions
    old_stat = File.stat(file_name)
  else
    # If not possible, probe which are the default permissions in the
    # destination directory.
    old_stat = probe_stat_in(File.dirname(file_name))
  end

  mode = old_stat ? old_stat.mode : nil

  # Create temporary file with identical permissions
  temp_file = File.new(rand_filename(file_name), "w", mode)
  temp_file.binmode
  return_val = yield temp_file
  temp_file.close

  # Overwrite original file with temp file
  File.rename(temp_file.path, file_name)

  # Unable to get permissions of the original file => return
  return return_val if old_stat.nil?

  # Set correct uid/gid on new file
  File.chown(old_stat.uid, old_stat.gid, file_name) if old_stat

  return_val
end