Class: VirtFS::VFile

Inherits:
VIO
  • Object
show all
Includes:
FileInstanceDelegate
Defined in:
lib/virtfs/v_file.rb

Overview

VirtFS File representation - implements the core Ruby File methods, dispatching to underlying mounted VirtFS filesystems

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from VIO

binread, copy_stream, foreach, open, pipe, popen, read, readlines, select, sysopen, try_convert

Constructor Details

#initialize(file_obj, path) ⇒ VFile

VFile initializer

Parameters:

  • file_obj (VirtFS::FS::File)

    handle to filesystem specific file obj

  • path (String)

    path at which the file resides



17
18
19
20
# File 'lib/virtfs/v_file.rb', line 17

def initialize(file_obj, path)
  @open_path = path
  __setobj__(file_obj)
end

Instance Attribute Details

#fs_mod_objObject

rubocop:disable ClassLength



6
7
8
# File 'lib/virtfs/v_file.rb', line 6

def fs_mod_obj
  @fs_mod_obj
end

Class Method Details

.absolute_path(f, dirstring = nil) ⇒ Object

Returns absolute path of file (across mounted filesystems).

Returns:

  • absolute path of file (across mounted filesystems)



102
103
104
105
# File 'lib/virtfs/v_file.rb', line 102

def absolute_path(f, dirstring = nil)
  dir = dirstring || VirtFS.dir_getwd
  VfsRealFile.absolute_path(f, dir)
end

.atime(f) ⇒ Time

Returns access time of the file.

Returns:

  • (Time)

    access time of the file



108
109
110
# File 'lib/virtfs/v_file.rb', line 108

def atime(f)
  VirtFS.fs_lookup_call(f) { |p| file_atime(p) }
end

.basename(*args) ⇒ String

Returns base name of the file.

Returns:

  • (String)

    base name of the file



113
114
115
# File 'lib/virtfs/v_file.rb', line 113

def basename(*args)
  VfsRealFile.basename(*args)
end

.blockdev?(f) ⇒ Boolean

Returns indicating if file is a block device.

Returns:

  • (Boolean)

    indicating if file is a block device



118
119
120
# File 'lib/virtfs/v_file.rb', line 118

def blockdev?(f)
  VirtFS.fs_lookup_call(f) { |p| file_blockdev?(p) }
end

.chardev?(f) ⇒ Boolean

Returns indicating if file is a char device.

Returns:

  • (Boolean)

    indicating if file is a char device



123
124
125
# File 'lib/virtfs/v_file.rb', line 123

def chardev?(f)
  VirtFS.fs_lookup_call(f) { |p| file_chardev?(p) }
end

.chmod(permission, *files) ⇒ Object

Change File ACLs

Parameters:

  • permission (Integer)

    new acl to assign to file(s)



130
131
132
133
134
135
136
# File 'lib/virtfs/v_file.rb', line 130

def chmod(permission, *files)
  nfp = 0
  files.each do |f|
    nfp += VirtFS.fs_lookup_call(f) { |p| file_chmod(permission, p) }
  end
  nfp
end

.chown(owner, group, *files) ⇒ Object

Change ownership / group ownership of file

Parameters:

  • owner (Integer, String)

    new owner of the file(s)

  • group (Integer, String)

    new group owner of the file(s)



142
143
144
145
146
147
148
149
150
# File 'lib/virtfs/v_file.rb', line 142

def chown(owner, group, *files)
  owner = owner.to_int
  group = group.to_int
  nfp = 0
  files.each do |f|
    nfp += VirtFS.fs_lookup_call(f) { |p| file_chown(owner, group, p) }
  end
  nfp
end

.ctime(f) ⇒ ]]

Returns Time] change time of time.

Returns:

  • (]])

    Time] change time of time



153
154
155
# File 'lib/virtfs/v_file.rb', line 153

def ctime(f)
  VirtFS.fs_lookup_call(f) { |p| file_ctime(p) }
end

.delete(*files) ⇒ Object Also known as: unlink

Delete specified files



158
159
160
161
162
163
164
# File 'lib/virtfs/v_file.rb', line 158

def delete(*files)
  nfp = 0
  files.each do |f|
    nfp += VirtFS.fs_lookup_call(f, false, false) { |p| file_delete(p) }
  end
  nfp
end

.directory?(f) ⇒ Boolean

Returns indiciating if file is a directory.

Returns:

  • (Boolean)

    indiciating if file is a directory



168
169
170
# File 'lib/virtfs/v_file.rb', line 168

def directory?(f)
  VirtFS.fs_lookup_call(f) { |p| file_directory?(p) }
end

.dirname(*args) ⇒ String

Returns containg file directory name.

Returns:

  • (String)

    containg file directory name



173
174
175
# File 'lib/virtfs/v_file.rb', line 173

def dirname(*args)
  VfsRealFile.dirname(*args)
end

.executable?(f) ⇒ Boolean

Returns indiciating if file is executable.

Returns:

  • (Boolean)

    indiciating if file is executable



178
179
180
# File 'lib/virtfs/v_file.rb', line 178

def executable?(f)
  VirtFS.fs_lookup_call(f) { |p| file_executable?(p) }
end

.executable_real?(f) ⇒ Boolean

Returns indiciating if file is executable and real.

Returns:

  • (Boolean)

    indiciating if file is executable and real



183
184
185
# File 'lib/virtfs/v_file.rb', line 183

def executable_real?(f)
  VirtFS.fs_lookup_call(f) { |p| file_executable_real?(p) }
end

.exist?(f) ⇒ Boolean Also known as: exists?

Returns indiciating if file exists.

Returns:

  • (Boolean)

    indiciating if file exists



188
189
190
# File 'lib/virtfs/v_file.rb', line 188

def exist?(f)
  VirtFS.fs_lookup_call(f) { |p| file_exist?(p) }
end

.expand_path(f, dirstring = nil) ⇒ String

Returns full expanded path to file.

Returns:

  • (String)

    full expanded path to file



194
195
196
197
# File 'lib/virtfs/v_file.rb', line 194

def expand_path(f, dirstring = nil)
  dir = dirstring || VirtFS.dir_getwd
  VfsRealFile.expand_path(f, dir)
end

.extname(*args) ⇒ String

Returns containg file extension name.

Returns:

  • (String)

    containg file extension name



200
201
202
# File 'lib/virtfs/v_file.rb', line 200

def extname(*args)
  VfsRealFile.extname(*args)
end

.file?(f) ⇒ Boolean

Returns indiciating if file is a regular file.

Returns:

  • (Boolean)

    indiciating if file is a regular file



205
206
207
# File 'lib/virtfs/v_file.rb', line 205

def file?(f)
  VirtFS.fs_lookup_call(f) { |p| file_file?(p) }
end

.fnmatch(*args) ⇒ Array<String> Also known as: fnmatch?

Returns names of files matching given args.

Returns:

  • (Array<String>)

    names of files matching given args



210
211
212
# File 'lib/virtfs/v_file.rb', line 210

def fnmatch(*args)
  VfsRealFile.fnmatch(*args)
end

.ftype(f) ⇒ Object

Returns type of file specified.

Returns:

  • type of file specified



216
217
218
# File 'lib/virtfs/v_file.rb', line 216

def ftype(f)
  VirtFS.fs_lookup_call(f) { |p| file_ftype(p) }
end

.grpowned?(f) ⇒ Boolean

Returns indicating if file is group owned.

Returns:

  • (Boolean)

    indicating if file is group owned



221
222
223
# File 'lib/virtfs/v_file.rb', line 221

def grpowned?(f)
  VirtFS.fs_lookup_call(f) { |p| file_grpowned?(p) }
end

.identical?(fname1, fname2) ⇒ Boolean

Returns indicating if files are identical.

Returns:

  • (Boolean)

    indicating if files are identical



226
227
228
229
230
231
# File 'lib/virtfs/v_file.rb', line 226

def identical?(fname1, fname2)
  fs1, p1 = VirtFS.path_lookup(fname1)
  fs2, p2 = VirtFS.path_lookup(fname2)
  return false unless fs1 == fs2
  VirtFS.fs_call(fs1) { file_identical?(p1, p2) }
end

.join(*args) ⇒ String

Returns containing joined path components.

Returns:

  • (String)

    containing joined path components



234
235
236
# File 'lib/virtfs/v_file.rb', line 234

def join(*args)
  VfsRealFile.join(*args)
end

.lchmod(permission, *files) ⇒ Object

Invoke a ‘lchmod’ on the given files

Parameters:

  • permission (Integer)

    new permission to assign to file(s)



242
243
244
245
246
247
248
# File 'lib/virtfs/v_file.rb', line 242

def lchmod(permission, *files)
  nfp = 0
  files.each do |f|
    nfp += VirtFS.fs_lookup_call(f) { |p| file_lchmod(permission, p) }
  end
  nfp
end

.lchown(owner, group, *files) ⇒ Object

Invoke a ‘lchown’ on the given files

Parameters:

  • owner (String)

    new owner to assign to file(s)

  • group (String)

    new group to assign to file(s)



255
256
257
258
259
260
261
# File 'lib/virtfs/v_file.rb', line 255

def lchown(owner, group, *files)
  nfp = 0
  files.each do |f|
    nfp += VirtFS.fs_lookup_call(f, false, false) { |p| file_lchown(owner, group, p) }
  end
  nfp
end

Create a symbol link between files

Parameters:

  • oname (String)

    file to link to

  • nname (String)

    symbolic link to create

Raises:

  • (SystemCallError)


268
269
270
271
272
273
# File 'lib/virtfs/v_file.rb', line 268

def link(oname, nname)
  fs1, p1 = VirtFS.path_lookup(oname)
  fs2, p2 = VirtFS.path_lookup(nname)
  raise SystemCallError, "Can't hard link between filesystems" unless fs1 == fs2 # TODO: check exception
  VirtFS.fs_call(fs1) { file_link(p1, p2) }
end

.lstat(f) ⇒ Stat

Returns file stat for specified file.

Returns:

  • (Stat)

    file stat for specified file



276
277
278
# File 'lib/virtfs/v_file.rb', line 276

def lstat(f)
  VirtFS.fs_lookup_call(f, false, false) { |p| file_lstat(p) }
end

.mtime(f) ⇒ Time

Returns modification time of the specified file.

Returns:

  • (Time)

    modification time of the specified file



281
282
283
# File 'lib/virtfs/v_file.rb', line 281

def mtime(f)
  VirtFS.fs_lookup_call(f) { |p| file_mtime(p) }
end

.new(file_id, *args) ⇒ Object

Instantiate new file instance.

Parameters:

  • file_id (String)

    file identifier (usually path)

  • args

    args to forward to file initializer



456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
# File 'lib/virtfs/v_file.rb', line 456

def new(file_id, *args) # rubocop:disable AbcSize
  if file_id.respond_to?(:to_int)
    fs_obj = VfsRealIO.new(file_id, *args)
  else
    parsed_args = FileModesAndOptions.new(*args)
    fs, p = VirtFS.path_lookup(file_id, false, false)
    fs_obj = VirtFS.fs_call(fs) { file_new(p, parsed_args, file_id, VDir.getwd) }
  end

  obj = allocate
  if fs.thin_interface?
    obj.send(:initialize, ThinFileDelegator.new(fs_obj, file_id, p, parsed_args), file_id)
  else
    obj.send(:initialize, fs_obj, file_id)
  end

  # fs_mod_obj always points to the fs module's file object
  # for use by fs-specific extension modules
  obj.fs_mod_obj = fs_obj
  obj.extend(fs_obj.extension_module) if fs_obj.respond_to?(:extension_module) # fs-specific extension module
  obj
end

.owned?(f) ⇒ Boolean

Returns indicating if file is owned.

Returns:

  • (Boolean)

    indicating if file is owned



286
287
288
# File 'lib/virtfs/v_file.rb', line 286

def owned?(f)
  VirtFS.fs_lookup_call(f) { |p| file_owned?(p) }
end

.path(obj) ⇒ Object

Returns path to specified file object.

Returns:

  • path to specified file object



291
292
293
# File 'lib/virtfs/v_file.rb', line 291

def path(obj)
  VfsRealFile.path(obj) # will check obj.to_path
end

.pipe?(f) ⇒ Boolean

Returns indicating if file is pipe.

Returns:

  • (Boolean)

    indicating if file is pipe



296
297
298
# File 'lib/virtfs/v_file.rb', line 296

def pipe?(f)
  VirtFS.fs_lookup_call(f) { |p| file_pipe?(p) }
end

.readable?(f) ⇒ Boolean

Returns indicating if file is readable.

Returns:

  • (Boolean)

    indicating if file is readable



301
302
303
# File 'lib/virtfs/v_file.rb', line 301

def readable?(f)
  VirtFS.fs_lookup_call(f) { |p| file_readable?(p) }
end

.readable_real?(f) ⇒ Boolean

Returns indicating if file is real and readable.

Returns:

  • (Boolean)

    indicating if file is real and readable



306
307
308
# File 'lib/virtfs/v_file.rb', line 306

def readable_real?(f)
  VirtFS.fs_lookup_call(f) { |p| file_readable_real?(p) }
end

Returns name of file references by link.

Returns:

  • (String)

    name of file references by link



311
312
313
# File 'lib/virtfs/v_file.rb', line 311

def readlink(f)
  VirtFS.fs_lookup_call(f, false, false) { |p| file_readlink(p) }
end

.realdirpath(path, relative_to = nil) ⇒ String

Returns real directory containing file.

Returns:

  • (String)

    real directory containing file



316
317
318
# File 'lib/virtfs/v_file.rb', line 316

def realdirpath(path, relative_to = nil) # ???
  VirtFS.expand_links(VirtFS.normalize_path(path, relative_to))
end

.realpath(path, relative_to = nil) ⇒ String

Returns real path of the file.

Returns:

  • (String)

    real path of the file



321
322
323
# File 'lib/virtfs/v_file.rb', line 321

def realpath(path, relative_to = nil) # ???
  VirtFS.expand_links(VirtFS.normalize_path(path, relative_to))
end

.rename(oname, nname) ⇒ Object

Rename file

Parameters:

  • oname (String)

    file to rename

  • nname (String)

    new name to assign to file

Raises:

  • (SystemCallError)


330
331
332
333
334
335
# File 'lib/virtfs/v_file.rb', line 330

def rename(oname, nname)
  fs1, p1 = VirtFS.path_lookup(oname)
  fs2, p2 = VirtFS.path_lookup(nname)
  raise SystemCallError, "Can't rename between filesystems" unless fs1 == fs2 # TODO: check exception
  VirtFS.fs_call(fs1) { file_rename(p1, p2) }
end

.setgid?(f) ⇒ Boolean

Returns indicating if file GID is set.

Returns:

  • (Boolean)

    indicating if file GID is set



338
339
340
# File 'lib/virtfs/v_file.rb', line 338

def setgid?(f)
  VirtFS.fs_lookup_call(f) { |p| file_setgid?(p) }
end

.setuid?(f) ⇒ Boolean

Returns indicating if file UID is set.

Returns:

  • (Boolean)

    indicating if file UID is set



343
344
345
# File 'lib/virtfs/v_file.rb', line 343

def setuid?(f)
  VirtFS.fs_lookup_call(f) { |p| file_setuid?(p) }
end

.size(f) ⇒ Integer

Returns size of the file in bytes.

Returns:

  • (Integer)

    size of the file in bytes



348
349
350
# File 'lib/virtfs/v_file.rb', line 348

def size(f)
  VirtFS.fs_lookup_call(f) { |p| file_size(p) }
end

.size?(f) ⇒ Integer?

Returns same as #size but return nil if empty.

Returns:

  • (Integer, nil)

    same as #size but return nil if empty



353
354
355
356
357
# File 'lib/virtfs/v_file.rb', line 353

def size?(f)
  sz = size(f)
  return nil if sz == 0
  sz
end

.socket?(f) ⇒ Boolean

Returns indicating if file is a socket.

Returns:

  • (Boolean)

    indicating if file is a socket



360
361
362
# File 'lib/virtfs/v_file.rb', line 360

def socket?(f)
  VirtFS.fs_lookup_call(f) { |p| file_socket?(p) }
end

.split(f) ⇒ Array<String>

Returns split file path.

Returns:

  • (Array<String>)

    split file path



365
366
367
# File 'lib/virtfs/v_file.rb', line 365

def split(f)
  VfsRealFile.split(f)
end

.stat(f) ⇒ Stat

Returns file stat correspond to file.

Returns:

  • (Stat)

    file stat correspond to file



370
371
372
# File 'lib/virtfs/v_file.rb', line 370

def stat(f)
  VirtFS.fs_lookup_call(f) { |p| file_stat(p) }
end

.sticky?(f) ⇒ Boolean

Returns indicating if file is sticky.

Returns:

  • (Boolean)

    indicating if file is sticky



375
376
377
# File 'lib/virtfs/v_file.rb', line 375

def sticky?(f)
  VirtFS.fs_lookup_call(f) { |p| file_sticky?(p) }
end

Create new symlink to file

Parameters:

  • oname (String)

    file to link to

  • nname (String)

    symbollic link to create



384
385
386
387
388
389
390
# File 'lib/virtfs/v_file.rb', line 384

def symlink(oname, nname)
  #
  # oname is the path to the original file in the global FS namespace.
  # It is not modified and used as the link target.
  #
  VirtFS.fs_lookup_call(nname) { |p| file_symlink(oname, p) }
end

.symlink?(f) ⇒ Boolean

Returns indicating if file is symlink.

Returns:

  • (Boolean)

    indicating if file is symlink



393
394
395
# File 'lib/virtfs/v_file.rb', line 393

def symlink?(f)
  VirtFS.fs_lookup_call(f, false, false) { |p| file_symlink?(p) }
end

.truncate(f, len) ⇒ Object

Truncate file to the specified len

Parameters:

  • f (String)

    file to truncate

  • len (Integer)

    length to truncate file to (in bytes)



401
402
403
# File 'lib/virtfs/v_file.rb', line 401

def truncate(f, len)
  VirtFS.fs_lookup_call(f) { |p| file_truncate(p, len) }
end

.umask(*args) ⇒ Integer

Returns umake of file.

Returns:

  • (Integer)

    umake of file



406
407
408
# File 'lib/virtfs/v_file.rb', line 406

def umask(*args)
  VfsRealFile.umask(*args)
end

.utime(atime, mtime, *files) ⇒ Object

Update file time

Parameters:

  • atime (Time)

    new access time to assign to file(s)

  • mtime (Time)

    new modification time to assign to file(s)



414
415
416
417
418
419
420
# File 'lib/virtfs/v_file.rb', line 414

def utime(atime, mtime, *files)
  nfp = 0
  files.each do |f|
    nfp += VirtFS.fs_lookup_call(f) { |p| file_utime(atime, mtime, p) }
  end
  nfp
end

.world_readable?(f) ⇒ Boolean

Returns indicating if file is world readable.

Returns:

  • (Boolean)

    indicating if file is world readable



423
424
425
# File 'lib/virtfs/v_file.rb', line 423

def world_readable?(f)
  VirtFS.fs_lookup_call(f) { |p| file_world_readable?(p) }
end

.world_writable?(f) ⇒ Boolean

Returns indicating if file is world writable.

Returns:

  • (Boolean)

    indicating if file is world writable



428
429
430
# File 'lib/virtfs/v_file.rb', line 428

def world_writable?(f)
  VirtFS.fs_lookup_call(f) { |p| file_world_writable?(p) }
end

.writable?(f) ⇒ Boolean

Returns indicating if file is writable.

Returns:

  • (Boolean)

    indicating if file is writable



433
434
435
# File 'lib/virtfs/v_file.rb', line 433

def writable?(f)
  VirtFS.fs_lookup_call(f) { |p| file_writable?(p) }
end

.writable_real?(f) ⇒ Boolean

Returns indicating if file is writable and real.

Returns:

  • (Boolean)

    indicating if file is writable and real



438
439
440
# File 'lib/virtfs/v_file.rb', line 438

def writable_real?(f)
  VirtFS.fs_lookup_call(f) { |p| file_writable_real?(p) }
end

.zero?(f) ⇒ Boolean

Returns:

  • (Boolean)


442
443
444
445
446
447
448
449
450
# File 'lib/virtfs/v_file.rb', line 442

def zero?(f)
  fs, p = VirtFS.path_lookup(f)
  begin
    VirtFS.fs_call(fs) { file_chardev?(p) }
    return fs.file_size(p) == 0
  rescue Errno::ENOENT
    return false
  end
end

Instance Method Details

#<<(obj) ⇒ Object

Some methods need to return the File object. Methods in the delegator object can’t do that, so we intercept them and do it here.



27
28
29
30
# File 'lib/virtfs/v_file.rb', line 27

def <<(obj)
  super
  self
end

#binmodeObject



32
33
34
35
# File 'lib/virtfs/v_file.rb', line 32

def binmode
  super
  self
end

#each(*args) ⇒ Object



37
38
39
40
# File 'lib/virtfs/v_file.rb', line 37

def each(*args)
  return self if (rv = super) == __getobj__
  rv
end

#each_byteObject



42
43
44
45
# File 'lib/virtfs/v_file.rb', line 42

def each_byte
  return self if (rv = super) == __getobj__
  rv
end

#each_charObject



47
48
49
50
# File 'lib/virtfs/v_file.rb', line 47

def each_char
  return self if (rv = super) == __getobj__
  rv
end

#each_codepointObject



52
53
54
55
# File 'lib/virtfs/v_file.rb', line 52

def each_codepoint
  return self if (rv = super) == __getobj__
  rv
end

#flushObject



57
58
59
60
# File 'lib/virtfs/v_file.rb', line 57

def flush
  return self if (rv = super) == __getobj__
  rv
end

#pathString

Returns path which dir resides.

Returns:

  • (String)

    path which dir resides



63
64
65
# File 'lib/virtfs/v_file.rb', line 63

def path
  @open_path
end

#reopen(*args) ⇒ Object

Reopens file with the given args



69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/virtfs/v_file.rb', line 69

def reopen(*args)
  new_path = nil
  if !args[0].respond_to?(:to_str) && args[0].respond_to?(:__getobj__)
    # Given an IO object.
    to_obj = args[0]
    args = [to_obj.__getobj__]
    new_path = to_obj.path
  end
  new_obj = __getobj__.reopen(*args)
  __setobj__(new_obj)
  @open_path = new_path || new_obj.path
  self
end

#set_encoding(*args) ⇒ Object



83
84
85
86
# File 'lib/virtfs/v_file.rb', line 83

def set_encoding(*args)
  super
  self
end

#to_ioObject



88
89
90
# File 'lib/virtfs/v_file.rb', line 88

def to_io
  self
end

#to_pathString

Returns path which dir resides.

Returns:

  • (String)

    path which dir resides



66
67
68
# File 'lib/virtfs/v_file.rb', line 66

def path
  @open_path
end