diff --git a/ext/hbsdctl.rb/ffi.c b/ext/hbsdctl.rb/ffi.c index 24d7db4..c3326c9 100644 --- a/ext/hbsdctl.rb/ffi.c +++ b/ext/hbsdctl.rb/ffi.c @@ -50,12 +50,16 @@ VALUE ffi_sysdef(VALUE self, VALUE rb_feature, VALUE rb_path) { struct Options options; - int r; - + int result; + errno = 0; options = __options_init(rb_feature, rb_path); - r = hbsdcontrol_extattr_rm_attr(options.path, options.disable_flag); - r &= hbsdcontrol_extattr_rm_attr(options.path, options.enable_flag); - return (r == 0 ? Qtrue : Qfalse); + result = hbsdcontrol_extattr_rm_attr(options.path, options.disable_flag) == 0 && + hbsdcontrol_extattr_rm_attr(options.path, options.enable_flag) == 0; + if (result) { + return (Qtrue); + } else { + rb_syserr_fail(errno, "hbsdcontrol_extattr_rm_attr"); + } } diff --git a/lib/bsd/control/feature.rb b/lib/bsd/control/feature.rb index a796d87..46b2f65 100644 --- a/lib/bsd/control/feature.rb +++ b/lib/bsd/control/feature.rb @@ -46,8 +46,8 @@ module BSD::Control # @param [String] path # The path to a file. # - # @raise [BSD::Control::Error] - # When the operation fails. + # @raise [SystemCallError] + # Might raise a number of Errno exceptions. # # @return [Boolean] # Returns true on success. diff --git a/test/unprivileged/feature_test.rb b/test/unprivileged/feature_test.rb index 3a01e93..26c6e80 100644 --- a/test/unprivileged/feature_test.rb +++ b/test/unprivileged/feature_test.rb @@ -1,6 +1,6 @@ require_relative "../setup" module BSD::Control - class FeatureBangTest < Test::Unit::TestCase + class FeatureTest < Test::Unit::TestCase def test_mprotect_feature assert_instance_of BSD::Control::Feature, BSD::Control.feature(:mprotect) diff --git a/test/unprivileged/sysdef_test.rb b/test/unprivileged/sysdef_test.rb new file mode 100644 index 0000000..ef11f77 --- /dev/null +++ b/test/unprivileged/sysdef_test.rb @@ -0,0 +1,22 @@ +require_relative "../setup" +module BSD::Control + class SysDefTest < Test::Unit::TestCase + require "fileutils" + include FileUtils + + def test_sysdef!_lacks_privileges + touch(file) + assert_raises(Errno::EPERM) do + BSD::Control.feature(:mprotect).sysdef!(file) + end + ensure + rm(file) + end + + private + + def file + File.join(__dir__, "file") + end + end +end