Skip to content

Commit a19228f

Browse files
committed
brace the fact that lchmod(2) can EOPNOTSUPP
Musl libc has this function as a tiny wrapper of fchmodat(3posix). On the other hand Linux kernel does not support changing modes of a symlink. The operation always fails with EOPNOTSUPP. This fchmodat behaviour is defined in POSIX. We have to take care of such exceptions.
1 parent 50925b6 commit a19228f

File tree

3 files changed

+15
-9
lines changed

3 files changed

+15
-9
lines changed

lib/fileutils.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1345,6 +1345,7 @@ def chmod(mode)
13451345
else
13461346
File.chmod mode, path()
13471347
end
1348+
rescue Errno::EOPNOTSUPP
13481349
end
13491350

13501351
def chown(uid, gid)
@@ -1439,7 +1440,7 @@ def copy_metadata(path)
14391440
if st.symlink?
14401441
begin
14411442
File.lchmod mode, path
1442-
rescue NotImplementedError
1443+
rescue NotImplementedError, Errno::EOPNOTSUPP
14431444
end
14441445
else
14451446
File.chmod mode, path

test/pathname/test_pathname.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -818,7 +818,7 @@ def test_lchmod
818818
old = path.lstat.mode
819819
begin
820820
path.lchmod(0444)
821-
rescue NotImplementedError
821+
rescue NotImplementedError, Errno::EOPNOTSUPP
822822
next
823823
end
824824
assert_equal(0444, path.lstat.mode & 0777)

test/ruby/test_notimp.rb

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@ def test_respond_to_fork
1313

1414
def test_respond_to_lchmod
1515
assert_include(File.methods, :lchmod)
16-
if /linux/ =~ RUBY_PLATFORM
17-
assert_equal(false, File.respond_to?(:lchmod))
18-
end
19-
if /freebsd/ =~ RUBY_PLATFORM
16+
case RUBY_PLATFORM
17+
when /freebsd/, /linux-musl/
2018
assert_equal(true, File.respond_to?(:lchmod))
19+
when /linux/
20+
assert_equal(false, File.respond_to?(:lchmod))
2121
end
2222
end
2323

@@ -57,9 +57,14 @@ def test_call_lchmod
5757
File.open(f, "w") {}
5858
File.symlink f, g
5959
newmode = 0444
60-
File.lchmod newmode, "#{d}/g"
61-
snew = File.lstat(g)
62-
assert_equal(newmode, snew.mode & 0777)
60+
begin
61+
File.lchmod newmode, "#{d}/g"
62+
rescue Errno::EOPNOTSUPP
63+
skip $!
64+
else
65+
snew = File.lstat(g)
66+
assert_equal(newmode, snew.mode & 0777)
67+
end
6368
}
6469
end
6570
end

0 commit comments

Comments
 (0)