lib/ffi/libfuse/fuse_context.rb in ffi-libfuse-0.0.1.rctest12 vs lib/ffi/libfuse/fuse_context.rb in ffi-libfuse-0.1.0.rc20220550
- old
+ new
@@ -13,14 +13,25 @@
include FFI::Accessors
base = { fuse: :fuse, uid: :uid_t, gid: :gid_t, pid: :pid_t, private_data: RubyObject }
base[:umask] = :mode_t if FUSE_VERSION >= 28
layout base
- ffi_attr_reader(:uid, :gid, :pid, :mode, :private_data)
+ ffi_attr_reader(*members, simple: false) do
+ m = __method__
- ffi_attr_reader(:umask) if FUSE_VERSION >= 28
+ # Use overrides if they are available, or the default context if the underlying memory is invalid
+ FuseContext.overrides[m] || (null? ? DEFAULT_CONTEXT[m] : self[m])
+ end
+ if FUSE_VERSION < 28
+ attr_writer :umask
+
+ def umask
+ @umask ||= File.umask
+ end
+ end
+
# @!attribute [r] uid
# @return [Integer] user id of the calling process
# @!attribute [r] gid
# @return [Integer] group id of the calling process
@@ -30,11 +41,13 @@
# @!attribute [r] private_data
# @return [Object] private filesystem data
# @see FuseOperations#init
- # @!attribute [r] umask
+ # @!attribute [rw] umask
+ #
+ # Writable only for Fuse version < 28
# @return [Integer] umask of the calling process
# @return [Boolean]
# @see Libfuse.fuse_interrupted?
def interrupted?
@@ -46,11 +59,40 @@
# @see Libfuse.raise_interrupt
def raise_interrupt
Libfuse.raise_interrupt
end
+ # @param [Integer] perms
+ # @return perms adjusted by {#umask}
+ def mask(perms)
+ perms & ~umask
+ end
+
+ DEFAULT_CONTEXT = { uid: Process.uid, gid: Process.gid, umask: File.umask }.freeze
+
class << self
+ # @overload overrides(hash)
+ # @param[Hash<Symbol,Object|nil] hash a list of override values that will apply to this context
+ #
+ # If not set uid, gid, umask will be overridden from the current process, which is useful if
+ # {FuseContext} is referenced from outside of a fuse callback
+ # @yield [] executes block with the given hash overriding FuseContext values
+ # @return [Object] the result of the block
+ # @overload overrides()
+ # @return [Hash] current thread local overrides for FuseContext
+ def overrides(hash = nil)
+ return Thread.current[:fuse_context_overrides] ||= {} unless block_given?
+
+ begin
+ Thread.current[:fuse_context_overrides] = hash || DEFAULT_CONTEXT
+ yield
+ ensure
+ Thread.current[:fuse_context_overrides] = nil
+ end
+ end
+
# @return [FuseContext] the context for the current filesystem operation
+ # @note if called outside a fuse callback the native {FuseContext} will have invalid values. See {overrides}
def fuse_get_context
Libfuse.fuse_get_context
end
alias get fuse_get_context
end