-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Write macOS implementation of ishidden #1
Comments
The current problem is that, although Julia has an |
Still need to use this output with some constant to infer whether this file is hidden or not This function (_sv_flags) could definitely be improved. One way would be to dynamically allocate required size, but I also hate that we are indexing stat buffer directly. The sv_flags field should always be in position 11 (or 21 if using 32-bit), but I still don't like it Addresses #1
Still need to use this output with some constant to infer whether this file is hidden or not This function (_sv_flags) could definitely be improved. One way would be to dynamically allocate required size, but I also hate that we are indexing stat buffer directly. The sv_flags field should always be in position 11 (or 21 if using 32-bit), but I still don't like it Addresses #1
After trialing many different methods for parsing the sv_flags output using UF_HIDDEN (all of which had varying resources), I think the one that works is the one I have implemented. This finalises the macOS implementation of this function. I still have improvements to add, as specified in d3ff556, but these can come later. Addresses #1. Leaving the issue open in the interest of improvements and verifying that _isinvisible is correctly defined.
Now that I have the const KLS_ITEM_INFO_IS_INVISIBLE = 0x00000040
_isinvisible(f::AbstractString) = !iszero(_sv_flags(f) & KLS_ITEM_INFO_IS_INVISIBLE)
const UF_HIDDEN = 0x00008000
_isinvisible(f::AbstractString) = !iszero(_sv_flags(f) | UF_HIDDEN)
const UF_HIDDEN = 0x00008000
_isinvisible(f::AbstractString) = !iszero(_sv_flags(f) & ~UF_HIDDEN) The implementation I ended up going with (seen implemented elsewhere[1], [2]), using the const UF_HIDDEN = 0x00008000
_isinvisible(f::AbstractString) = (_sv_flags(f) & UF_HIDDEN) == UF_HIDDEN |
Based on 'Apple Developer Documentation - Hidden Files and Directories: Simplifying the User Experience', I still have a couple of things to implement (some addressing separate issues as well):
|
Addresses #1. getxattr does not actually get what I want, as we need to parse whatever `mdls` uses to get file metadata, however I am commiting this now in case getxattr does come in handy Also added comments for the other cases, as per https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html#//apple_ref/doc/uid/TP40010672-CH2-SW7
Even though . and .. directories start with ., they should be excluded from being hidden Addresses #1
Addresses #1. It occurred to me that we don't need to check . and .. if we can expand the path to ignore any relative path components
Addresses #1. In this commit I have removed any old work using getxattr, as getxattr deals with extended attributes (metadata) attached to files. They're actually unrelated to ext. attrs.: mdls involves higher level stuff that makes calls into LaunchServices and uses the LS database. I have discovered (using nm) that in particular, mdls makes calls to MDItemCopyAttributeNames and MDItemCopyAttributes. As such I have been working on porting over logic using these C calls. However, MDItem* functions require path names to be CFStrings, so a lot of work has gone into different encodings (thanks Apple). I still need to get the _mdls function working as expected, as currently I presumably have the attribute list using MDItemCreate and MDItemCopyAttributeNames, however I need to parse it correctly and extract the attribute that I want to use to determine if the path is a package or a bundle.
Addresses #1. After a _lot_ of trial and error, I figured out I was using the wrong function call! I was calling MDItemCopyAttributeNames rather than MDItemCopyAttribute (at which point I needed to _specify_ the attribute name myself). After this point, it was relatively easy to get this all working. Now I just need to clean up old functions I didn't end up using.
After all of the trial and error, there were some functions that were unused, and some variables misnamed Addresses #1
Importantly, the file or directory is hidden if one of its parents are contained in a package or bundle. Also added tests for this case. Addresses #1
Does checking for packages and bundles actually matter? If a file is contained within a package or bundle, is it really hidden? Should we only enable this feature with a flag? I will raise this with the others. EDIT: see #16. |
BSD-related OS's (i.e., FreeBSD and macOS) can have the st_flags check applied to them (as I implemented this for macOS), so this function was moved out into a separate branch. ZFS function stubs were also created (with errors in case people try to use them at this stage in development) so that I can (hopefully soon) start implementing them. Addresses #1, #3, #12, #13
Apparently you can get ZFS on macOS: https://github.com/openzfsonosx/zfs Addresses #1, #12, #13
Getting back to the task of checking whether a directory is a _system_ directory, I reviewed an old link I posted in #1: https://stackoverflow.com/a/1140345/12069968. While a lot of these function appear to be deprecated now, it seems to work somewhat well. For example, `_isinvisible_alt` returns `true` on all UNIX-specific directories listed in the macOS resources for this type of hidden file. We still need to: - Implement tests for all of these UNIX-specific directories; - Find non-deprecated system calls to obtain the same information; - Correctly construct LSItemInfoRecord (rather than allocating a reasonably large buffer because I don't know how large it needs to be), and find the correct offset for flags. Addresses #1 Ref: #1 (comment) ``` julia> HiddenFiles._isinvisible_alt("/bin") true julia> HiddenFiles._isinvisible_alt("/dev/") true julia> HiddenFiles._isinvisible_alt("/dev") true julia> HiddenFiles._isinvisible_alt("/etc") true julia> HiddenFiles._isinvisible_alt("/sbin/") true julia> HiddenFiles._isinvisible_alt("/sbin") true julia> HiddenFiles._isinvisible_alt("/tmp") true julia> HiddenFiles._isinvisible_alt("/usr") true julia> HiddenFiles._isinvisible_alt("/var") true ```
macOS implementation is difficult, because it follows UNIX conventions whilst also having some other information.
As far as I can tell, the only other thing that determines whether a file is hidden in macOS is a certain attribute in finder flags. Once I finish this implementation, I should confirm with Stefan, as he may know about some other file attributes that we need to check (in his comment he mentions there are three, on top of the UNIX standard).
Related:
stat.jl
sys.c
kLSItemInfoIsInvisible
LSItemInfoRecord
LSItemInfoFlags
hfs_format.h
fstat
chflags
The text was updated successfully, but these errors were encountered: