memfs 0.5.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.github/dependabot.yml +19 -0
- data/.github/workflows/ci.yml +64 -0
- data/.gitignore +1 -0
- data/.rspec +2 -2
- data/.rubocop.yml +81 -12
- data/CHANGELOG.md +41 -10
- data/Gemfile +19 -0
- data/Guardfile +5 -3
- data/README.md +7 -6
- data/Rakefile +4 -2
- data/bin/_guard-core +16 -0
- data/bin/coverage_summary +51 -0
- data/bin/guard +16 -0
- data/bin/rake +16 -0
- data/bin/rspec +16 -0
- data/bin/rubocop +16 -0
- data/lib/memfs/dir.rb +86 -21
- data/lib/memfs/fake/directory.rb +31 -3
- data/lib/memfs/fake/entry.rb +41 -25
- data/lib/memfs/fake/file/content.rb +6 -5
- data/lib/memfs/fake/file.rb +6 -5
- data/lib/memfs/fake/symlink.rb +2 -0
- data/lib/memfs/file/stat.rb +21 -14
- data/lib/memfs/file.rb +92 -77
- data/lib/memfs/file_system.rb +17 -12
- data/lib/memfs/filesystem_access.rb +2 -0
- data/lib/memfs/io.rb +183 -153
- data/lib/memfs/version.rb +3 -1
- data/lib/memfs.rb +112 -5
- data/memfs.gemspec +0 -14
- data/spec/fileutils_spec.rb +86 -58
- data/spec/memfs/dir_spec.rb +175 -27
- data/spec/memfs/fake/directory_spec.rb +8 -4
- data/spec/memfs/fake/entry_spec.rb +16 -10
- data/spec/memfs/fake/file/content_spec.rb +1 -1
- data/spec/memfs/fake/file_spec.rb +1 -1
- data/spec/memfs/fake/symlink_spec.rb +3 -3
- data/spec/memfs/file/stat_spec.rb +30 -15
- data/spec/memfs/file_spec.rb +271 -104
- data/spec/memfs/file_system_spec.rb +20 -19
- data/spec/memfs_spec.rb +67 -2
- data/spec/spec_helper.rb +40 -23
- metadata +17 -135
- data/.travis.yml +0 -6
data/lib/memfs/dir.rb
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'tmpdir'
|
|
1
4
|
require 'memfs/filesystem_access'
|
|
2
5
|
|
|
3
6
|
module MemFs
|
|
@@ -6,6 +9,8 @@ module MemFs
|
|
|
6
9
|
include Enumerable
|
|
7
10
|
include FilesystemAccess
|
|
8
11
|
|
|
12
|
+
Tmpname = MemFs::OriginalDir::Tmpname
|
|
13
|
+
|
|
9
14
|
attr_reader :pos
|
|
10
15
|
|
|
11
16
|
def self.[](*patterns)
|
|
@@ -17,15 +22,26 @@ module MemFs
|
|
|
17
22
|
0
|
|
18
23
|
end
|
|
19
24
|
|
|
25
|
+
if MemFs.ruby_version_gte?('2.6')
|
|
26
|
+
def self.children(dirname, opts = {})
|
|
27
|
+
entries(dirname, opts) - %w[. ..]
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
20
31
|
def self.chroot(path)
|
|
21
32
|
fail Errno::EPERM, path unless Process.uid.zero?
|
|
22
33
|
|
|
23
34
|
dir = fs.find_directory!(path)
|
|
24
|
-
dir.name =
|
|
35
|
+
dir.name = MemFs.platform_root
|
|
25
36
|
fs.root = dir
|
|
26
37
|
0
|
|
27
38
|
end
|
|
28
39
|
|
|
40
|
+
def self.empty?(path)
|
|
41
|
+
entry = fs.find!(path)
|
|
42
|
+
File.directory?(path) && entry.empty?
|
|
43
|
+
end
|
|
44
|
+
|
|
29
45
|
def self.entries(dirname, _opts = {})
|
|
30
46
|
fs.entries(dirname)
|
|
31
47
|
end
|
|
@@ -33,7 +49,7 @@ module MemFs
|
|
|
33
49
|
def self.exists?(path)
|
|
34
50
|
File.directory?(path)
|
|
35
51
|
end
|
|
36
|
-
class << self;
|
|
52
|
+
class << self; alias exist? exists?; end
|
|
37
53
|
|
|
38
54
|
def self.foreach(dirname, &block)
|
|
39
55
|
return to_enum(__callee__, dirname) unless block
|
|
@@ -44,27 +60,44 @@ module MemFs
|
|
|
44
60
|
def self.getwd
|
|
45
61
|
fs.getwd
|
|
46
62
|
end
|
|
47
|
-
class << self;
|
|
63
|
+
class << self; alias pwd getwd; end
|
|
48
64
|
|
|
49
|
-
|
|
50
|
-
|
|
65
|
+
# rubocop:disable Lint/UnderscorePrefixedVariableName, Lint/UnusedMethodArgument
|
|
66
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
|
|
67
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
|
68
|
+
def self.glob(patterns, _flags = 0, flags: _flags, base: nil, sort: true, &block)
|
|
69
|
+
# rubocop:enable Lint/UnderscorePrefixedVariableName, Lint/UnusedMethodArgument
|
|
70
|
+
original_patterns = [*patterns].map(&:to_s)
|
|
71
|
+
# Normalize patterns for platform (e.g., '/test' -> 'D:/test' on Windows)
|
|
72
|
+
normalized_patterns = original_patterns.map { |p| MemFs.normalize_path(p) }
|
|
51
73
|
list = fs.paths.select do |path|
|
|
52
|
-
|
|
74
|
+
normalized_patterns.any? do |pattern|
|
|
53
75
|
File.fnmatch?(pattern, path, flags | GLOB_FLAGS)
|
|
54
76
|
end
|
|
55
77
|
end
|
|
56
|
-
|
|
57
|
-
|
|
78
|
+
|
|
79
|
+
# Special case for /* and /
|
|
80
|
+
# A scenario where /* is not the only pattern and / should be returned is
|
|
81
|
+
# considered an edge-case (platform-aware root handling).
|
|
82
|
+
root_pattern = MemFs.windows? ? "#{MemFs.platform_root}*" : '/*'
|
|
83
|
+
if ['/*', root_pattern].include?(original_patterns.first)
|
|
84
|
+
list.delete(MemFs.platform_root)
|
|
85
|
+
list.delete('/') # Also handle Unix-style if passed
|
|
86
|
+
end
|
|
87
|
+
|
|
58
88
|
return list unless block_given?
|
|
59
|
-
|
|
89
|
+
|
|
90
|
+
list.each(&block)
|
|
60
91
|
nil
|
|
61
92
|
end
|
|
93
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
|
|
94
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
|
62
95
|
|
|
63
96
|
def self.home(*args)
|
|
64
97
|
original_dir_class.home(*args)
|
|
65
98
|
end
|
|
66
99
|
|
|
67
|
-
def self.mkdir(path, mode =
|
|
100
|
+
def self.mkdir(path, mode = 0o777)
|
|
68
101
|
fs.mkdir path, mode
|
|
69
102
|
end
|
|
70
103
|
|
|
@@ -77,7 +110,7 @@ module MemFs
|
|
|
77
110
|
dir
|
|
78
111
|
end
|
|
79
112
|
ensure
|
|
80
|
-
dir
|
|
113
|
+
dir&.close if block_given?
|
|
81
114
|
end
|
|
82
115
|
|
|
83
116
|
def self.rmdir(path)
|
|
@@ -85,12 +118,37 @@ module MemFs
|
|
|
85
118
|
end
|
|
86
119
|
|
|
87
120
|
def self.tmpdir
|
|
88
|
-
'
|
|
121
|
+
File.join(MemFs.platform_root, 'tmp')
|
|
89
122
|
end
|
|
90
123
|
|
|
124
|
+
# rubocop:disable Metrics/MethodLength
|
|
125
|
+
def self.mktmpdir(prefix_suffix = nil, tmpdir = nil, **options)
|
|
126
|
+
tmpdir = MemFs.normalize_path(tmpdir || self.tmpdir)
|
|
127
|
+
path = MemFs::OriginalDir::Tmpname.create(
|
|
128
|
+
prefix_suffix || 'd',
|
|
129
|
+
tmpdir,
|
|
130
|
+
**options) { |p, _, _, _d| mkdir(p, 0o700) }
|
|
131
|
+
|
|
132
|
+
# Normalize the returned path for consistent handling across platforms
|
|
133
|
+
path = MemFs.normalize_path(path)
|
|
134
|
+
|
|
135
|
+
return path unless block_given?
|
|
136
|
+
|
|
137
|
+
begin
|
|
138
|
+
yield path.dup
|
|
139
|
+
ensure
|
|
140
|
+
begin
|
|
141
|
+
rmdir(path) if exists?(path)
|
|
142
|
+
rescue StandardError
|
|
143
|
+
# Ignore cleanup errors
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
# rubocop:enable Metrics/MethodLength
|
|
148
|
+
|
|
91
149
|
class << self
|
|
92
|
-
|
|
93
|
-
|
|
150
|
+
alias delete rmdir
|
|
151
|
+
alias unlink rmdir
|
|
94
152
|
end
|
|
95
153
|
|
|
96
154
|
def initialize(path)
|
|
@@ -110,15 +168,21 @@ module MemFs
|
|
|
110
168
|
entry.entry_names.each(&block)
|
|
111
169
|
end
|
|
112
170
|
|
|
171
|
+
def fileno
|
|
172
|
+
entry.fileno
|
|
173
|
+
end
|
|
174
|
+
|
|
113
175
|
def path
|
|
114
176
|
entry.path
|
|
115
177
|
end
|
|
116
|
-
|
|
178
|
+
alias to_path path
|
|
117
179
|
|
|
180
|
+
# rubocop:disable Lint/Void
|
|
118
181
|
def pos=(position)
|
|
119
182
|
seek(position)
|
|
120
183
|
position
|
|
121
184
|
end
|
|
185
|
+
# rubocop:enable Lint/Void
|
|
122
186
|
|
|
123
187
|
def read
|
|
124
188
|
name = entries[pos]
|
|
@@ -141,13 +205,14 @@ module MemFs
|
|
|
141
205
|
@pos
|
|
142
206
|
end
|
|
143
207
|
|
|
144
|
-
|
|
208
|
+
GLOB_FLAGS = if defined?(File::FNM_EXTGLOB)
|
|
209
|
+
File::FNM_EXTGLOB | File::FNM_PATHNAME
|
|
210
|
+
else
|
|
211
|
+
File::FNM_PATHNAME
|
|
212
|
+
end
|
|
213
|
+
private_constant :GLOB_FLAGS
|
|
145
214
|
|
|
146
|
-
|
|
147
|
-
GLOB_FLAGS = File::FNM_EXTGLOB | File::FNM_PATHNAME
|
|
148
|
-
else
|
|
149
|
-
GLOB_FLAGS = File::FNM_PATHNAME
|
|
150
|
-
end
|
|
215
|
+
private
|
|
151
216
|
|
|
152
217
|
attr_accessor :entry, :max_seek, :state
|
|
153
218
|
|
data/lib/memfs/fake/directory.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'memfs/fake/entry'
|
|
2
4
|
|
|
3
5
|
module MemFs
|
|
@@ -18,8 +20,20 @@ module MemFs
|
|
|
18
20
|
entries.keys
|
|
19
21
|
end
|
|
20
22
|
|
|
23
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
21
24
|
def find(path)
|
|
22
|
-
path =
|
|
25
|
+
path = MemFs.normalize_path(path)
|
|
26
|
+
|
|
27
|
+
# Strip root prefix if present (platform_root first, then directory name for root dirs)
|
|
28
|
+
if path.start_with?(MemFs.platform_root)
|
|
29
|
+
path = path[MemFs.platform_root.length..]
|
|
30
|
+
elsif root_directory? && path.start_with?(name)
|
|
31
|
+
path = path[name.length..]
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
path = path.gsub(%r{(\A/+|/+\z)}, '')
|
|
35
|
+
return self if path.empty?
|
|
36
|
+
|
|
23
37
|
parts = path.split('/', 2)
|
|
24
38
|
|
|
25
39
|
if entry_names.include?(path)
|
|
@@ -28,6 +42,7 @@ module MemFs
|
|
|
28
42
|
entries[parts.first].find(parts.last)
|
|
29
43
|
end
|
|
30
44
|
end
|
|
45
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
31
46
|
|
|
32
47
|
def initialize(*args)
|
|
33
48
|
super
|
|
@@ -40,11 +55,18 @@ module MemFs
|
|
|
40
55
|
end
|
|
41
56
|
|
|
42
57
|
def path
|
|
43
|
-
|
|
58
|
+
root_directory? ? name : super
|
|
44
59
|
end
|
|
45
60
|
|
|
46
61
|
def paths
|
|
47
|
-
|
|
62
|
+
current_or_parent_dirs = %w[. ..]
|
|
63
|
+
|
|
64
|
+
[path] +
|
|
65
|
+
entries
|
|
66
|
+
.reject { current_or_parent_dirs.include?(_1) }
|
|
67
|
+
.values
|
|
68
|
+
.map(&:paths)
|
|
69
|
+
.flatten
|
|
48
70
|
end
|
|
49
71
|
|
|
50
72
|
def remove_entry(entry)
|
|
@@ -54,6 +76,12 @@ module MemFs
|
|
|
54
76
|
def type
|
|
55
77
|
'directory'
|
|
56
78
|
end
|
|
79
|
+
|
|
80
|
+
private
|
|
81
|
+
|
|
82
|
+
def root_directory?
|
|
83
|
+
parent.nil? || MemFs.root_path?(name)
|
|
84
|
+
end
|
|
57
85
|
end
|
|
58
86
|
end
|
|
59
87
|
end
|
data/lib/memfs/fake/entry.rb
CHANGED
|
@@ -1,29 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module MemFs
|
|
2
4
|
module Fake
|
|
3
5
|
class Entry
|
|
4
|
-
UREAD =
|
|
5
|
-
UWRITE =
|
|
6
|
-
UEXEC =
|
|
7
|
-
GREAD =
|
|
8
|
-
GWRITE =
|
|
9
|
-
GEXEC =
|
|
10
|
-
OREAD =
|
|
11
|
-
OWRITE =
|
|
12
|
-
OEXEC =
|
|
13
|
-
RSTICK =
|
|
14
|
-
USTICK =
|
|
15
|
-
SETUID =
|
|
16
|
-
SETGID =
|
|
6
|
+
UREAD = 0o0400
|
|
7
|
+
UWRITE = 0o0200
|
|
8
|
+
UEXEC = 0o0100
|
|
9
|
+
GREAD = 0o0040
|
|
10
|
+
GWRITE = 0o0020
|
|
11
|
+
GEXEC = 0o0010
|
|
12
|
+
OREAD = 0o0004
|
|
13
|
+
OWRITE = 0o0002
|
|
14
|
+
OEXEC = 0o0001
|
|
15
|
+
RSTICK = 0o1000
|
|
16
|
+
USTICK = 0o5000
|
|
17
|
+
SETUID = 0o4000
|
|
18
|
+
SETGID = 0o2000
|
|
17
19
|
|
|
18
20
|
attr_accessor :atime,
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
:birthtime,
|
|
22
|
+
:block_device,
|
|
23
|
+
:character_device,
|
|
24
|
+
:ctime,
|
|
25
|
+
:gid,
|
|
26
|
+
:mtime,
|
|
27
|
+
:name,
|
|
28
|
+
:parent,
|
|
29
|
+
:uid
|
|
27
30
|
attr_reader :mode
|
|
28
31
|
|
|
29
32
|
def blksize
|
|
@@ -50,31 +53,44 @@ module MemFs
|
|
|
50
53
|
@dev ||= rand(1000)
|
|
51
54
|
end
|
|
52
55
|
|
|
56
|
+
def fileno
|
|
57
|
+
fail NotImplementedError
|
|
58
|
+
end
|
|
59
|
+
|
|
53
60
|
def find(_path)
|
|
54
61
|
fail Errno::ENOTDIR, path
|
|
55
62
|
end
|
|
56
63
|
|
|
64
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
|
57
65
|
def initialize(path = nil)
|
|
58
66
|
time = Time.now
|
|
59
67
|
self.atime = time
|
|
68
|
+
self.birthtime = time
|
|
60
69
|
self.ctime = time
|
|
61
70
|
self.gid = Process.egid
|
|
62
|
-
self.mode =
|
|
71
|
+
self.mode = 0o666 - MemFs::File.umask
|
|
63
72
|
self.mtime = time
|
|
64
|
-
|
|
73
|
+
# Preserve full path for root directories (e.g., 'D:/' on Windows)
|
|
74
|
+
# since File.basename('D:/') returns '/' which breaks path matching
|
|
75
|
+
self.name = if path && MemFs.root_path?(path)
|
|
76
|
+
MemFs.normalize_path(path)
|
|
77
|
+
else
|
|
78
|
+
MemFs::File.basename(path || '')
|
|
79
|
+
end
|
|
65
80
|
self.uid = Process.euid
|
|
66
81
|
end
|
|
82
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
|
67
83
|
|
|
68
84
|
def ino
|
|
69
85
|
@ino ||= rand(1000)
|
|
70
86
|
end
|
|
71
87
|
|
|
72
88
|
def mode=(mode_int)
|
|
73
|
-
@mode =
|
|
89
|
+
@mode = 0o100000 | mode_int
|
|
74
90
|
end
|
|
75
91
|
|
|
76
92
|
def path
|
|
77
|
-
parts = [parent
|
|
93
|
+
parts = [parent&.path, name].compact
|
|
78
94
|
MemFs::File.join(parts)
|
|
79
95
|
end
|
|
80
96
|
|
|
@@ -1,16 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'delegate'
|
|
2
4
|
|
|
3
5
|
module MemFs
|
|
4
6
|
module Fake
|
|
5
7
|
class File < Entry
|
|
6
|
-
|
|
7
8
|
class Content < SimpleDelegator
|
|
8
9
|
attr_accessor :pos
|
|
9
10
|
|
|
10
|
-
def close
|
|
11
|
-
end
|
|
11
|
+
def close; end
|
|
12
12
|
|
|
13
13
|
def initialize(obj = '')
|
|
14
|
+
super
|
|
15
|
+
|
|
14
16
|
@string = obj.to_s.dup
|
|
15
17
|
@pos = 0
|
|
16
18
|
|
|
@@ -25,7 +27,7 @@ module MemFs
|
|
|
25
27
|
end
|
|
26
28
|
end
|
|
27
29
|
|
|
28
|
-
def read(length = nil, buffer = '')
|
|
30
|
+
def read(length = nil, buffer = +'')
|
|
29
31
|
length ||= @string.length - @pos
|
|
30
32
|
buffer.replace @string[@pos, length]
|
|
31
33
|
@pos += buffer.bytesize
|
|
@@ -46,7 +48,6 @@ module MemFs
|
|
|
46
48
|
text.size
|
|
47
49
|
end
|
|
48
50
|
end
|
|
49
|
-
|
|
50
51
|
end
|
|
51
52
|
end
|
|
52
53
|
end
|
data/lib/memfs/fake/file.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'memfs/fake/entry'
|
|
2
4
|
require 'memfs/fake/file/content'
|
|
3
5
|
|
|
@@ -33,11 +35,10 @@ module MemFs
|
|
|
33
35
|
end
|
|
34
36
|
|
|
35
37
|
def type
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
end
|
|
38
|
+
return 'blockSpecial' if block_device
|
|
39
|
+
return 'characterSpecial' if character_device
|
|
40
|
+
|
|
41
|
+
'file'
|
|
41
42
|
end
|
|
42
43
|
end
|
|
43
44
|
end
|
data/lib/memfs/fake/symlink.rb
CHANGED
data/lib/memfs/file/stat.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'forwardable'
|
|
2
4
|
require 'memfs/filesystem_access'
|
|
3
5
|
|
|
@@ -10,18 +12,19 @@ module MemFs
|
|
|
10
12
|
attr_reader :entry
|
|
11
13
|
|
|
12
14
|
def_delegators :entry,
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
15
|
+
:atime,
|
|
16
|
+
:birthtime,
|
|
17
|
+
:blksize,
|
|
18
|
+
:ctime,
|
|
19
|
+
:dev,
|
|
20
|
+
:gid,
|
|
21
|
+
:ino,
|
|
22
|
+
:mode,
|
|
23
|
+
:mtime,
|
|
24
|
+
:uid
|
|
22
25
|
|
|
23
26
|
def blockdev?
|
|
24
|
-
!!
|
|
27
|
+
!!entry.block_device
|
|
25
28
|
end
|
|
26
29
|
|
|
27
30
|
def chardev?
|
|
@@ -52,11 +55,15 @@ module MemFs
|
|
|
52
55
|
gid == Process.egid
|
|
53
56
|
end
|
|
54
57
|
|
|
55
|
-
def initialize(path, dereference
|
|
58
|
+
def initialize(path, dereference: false)
|
|
56
59
|
entry = fs.find!(path)
|
|
57
60
|
@entry = dereference ? entry.dereferenced : entry
|
|
58
61
|
end
|
|
59
62
|
|
|
63
|
+
def nlink
|
|
64
|
+
directory? ? 2 : 1
|
|
65
|
+
end
|
|
66
|
+
|
|
60
67
|
def owned?
|
|
61
68
|
uid == Process.euid
|
|
62
69
|
end
|
|
@@ -94,11 +101,11 @@ module MemFs
|
|
|
94
101
|
end
|
|
95
102
|
|
|
96
103
|
def world_readable?
|
|
97
|
-
entry.mode -
|
|
104
|
+
entry.mode - 0o100000 if (entry.mode & Fake::Entry::OREAD).nonzero?
|
|
98
105
|
end
|
|
99
106
|
|
|
100
107
|
def world_writable?
|
|
101
|
-
entry.mode -
|
|
108
|
+
entry.mode - 0o100000 if (entry.mode & Fake::Entry::OWRITE).nonzero?
|
|
102
109
|
end
|
|
103
110
|
|
|
104
111
|
def writable?
|
|
@@ -164,7 +171,7 @@ module MemFs
|
|
|
164
171
|
end
|
|
165
172
|
|
|
166
173
|
def world_executable?
|
|
167
|
-
entry.mode -
|
|
174
|
+
entry.mode - 0o100000 if (entry.mode & Fake::Entry::OEXEC).nonzero?
|
|
168
175
|
end
|
|
169
176
|
end
|
|
170
177
|
end
|