Comments (10)
Unfortunately, this has not been easy so far, given limitations about what symbols I have access to (using your
nm --dynamic
trick); hint: not all of the functions in ZFS's source I have access to...
Some things to note regarding nm
:
--defined-only
may be additionally useful for identifying what's directly available vs. linked from elsewhere (ldd
will tell you what it's linking to)nm
doesn't have struct namesnm
doesn't have anything defined as a preprocessor macro (e.g.f
in#define f(x) ...
)
Also, if you're doing this on FreeBSD, I recommend looking at the OpenZFS included in FreeBSD's monolithic source tree in case there are any differences compared to upstream.
from hiddenfiles.jl.
Do you know how exactly to call structs
What do you mean by "call" in this case? If you define a Julia type with a layout compatible with the C struct, you can return objects with that type from ccall
. Say for example you have
typedef struct _t {
int a;
int b;
} t;
void populate_t(t* thing) { ... }
then you can do
struct T
a::Cint
b::Cint
end
t = Ref{T}()
ccall((:populate_t, libwhatever), Cvoid, (Ref{T},), t)
(completely untested example but that's the gist). How exactly you go about it depends on the functions available from the library you're calling into.
definitions as a preprocessor macros
You'd have to reference whatever the macro expands to in your call on the Julia side since C macros exist only during the preprocessor phase; a compiled library has no knowledge of whether some part of its code was generated by a macro.
Or even how to call anything of the "D" type that
nm
displays
You need cglobal
:
julia> cglobal((:zfs_attr_table, "/lib/libzpool.so.2"))
Ptr{Nothing} @0x0000000895cdaf20
do you know anything about how I might programmatically check if a file is stored on a ZFS partition?
Unfortunately I don't, sorry
from hiddenfiles.jl.
The problem with
znode_t
is that I can't find it in any of the object files, so I guess I will have to figure out another way to get theznode
struct.
You wouldn't find znode_t
itself in an object file but you may find a function that returns a znode_t
(or, more likely, a pointer to one).
Potentially stupid question, but how do you actually use the result? It's a pointer to some object in memory, but I'm not sure how exactly to make that into an array or whatever it should be.
That's not a stupid question at all. The crucial piece here is "whatever it should be," as what it should be will determine how you go about retrieving that. cglobal
has another positional argument that tells it the type of data being referenced, and what you get back is a pointer with that type. If you want to turn it into a Julia array, you can use unsafe_wrap
, or you can unsafe_load
individual indices.
from hiddenfiles.jl.
It appears that BSD also has the UF_HIDDEN
flag in chflags, so they have this in common. Furthermore, as FreeBSD uses ZFS, there is another type of hidden file: snapshots of ZFS mounts are hidden, even from ls -a
. Currently working on figuring out from source how to pull this information myself. To do this I will also need to implement an iszfs
check, which may, in and of itself, be no mean task.
from hiddenfiles.jl.
I spent a long time looking through the source of OpenZFS (see above). After many possible avenues, I wanted to actually some real code, however suddenly I couldn't even do it in C; use of undeclared identifier 'znode_t'
. I asked resident FreeBSD Γ Julia enthusiast @ararslan, who told me that many FreeBSD functions are obtained from object files, most of which tucked away in the /lib
directory. Helpfully, Alex told me, you can get exposed functions by the command nm --dynamic <object file>
(the second time both in this project and in my life that I've used the nm
command!). I wanted to search all throughout this /lib
directory so I wrote:
function main(strs::String...)
io = IOBuffer()
for f in readdir("/lib", join = true)
isfile(f) || continue
try
run(pipeline(`nm --dynamic $f`, stdout = io, stderr = devnull))
cmd_out = lowercase(String(take!(io)))
any(occursin(s, cmd_out) for s in strs) && println(f)
finally
continue
end
end
end
I figured out that there are also many object files in the /usr/lib
directory.
Making good progress now that we
- have a background understanding of what to look for once we get some ZFS structures created (from all the code scouring);
- have a way to search available functions (thanks Alex); and
- know where the libraries are stored for running this in Julia!
from hiddenfiles.jl.
I should also note that this depends on ZFS, rather than FreeBSD
from hiddenfiles.jl.
At least as I understand it, hidden files on BSDs are the same as on Linux (and likely macOS). While FreeBSD can use ZFS, it doesn't have to; installers let you pick between UFS and ZFS with the former actually being the default for prebuilt VM images.
Are you looking to implement ishidden
on systems using ZFS such that a path pointing to some object within a ZFS control directory (.zfs
at the ZFS VFS mountpoint) is considered hidden? If so, you may be able to locate the mount points of all snapshots and check that the path falls within one of those. Also, this may provide some useful information for you: https://github.com/freebsd/freebsd-src/blob/271171e0d97b88ba2a7c3bf750c9672b484c1c13/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ctldir.c#L27-L66
from hiddenfiles.jl.
@ararslan yeah, I realised that when I started looking into this, that the .zfs
files are specific to ZSF rather than BSD. I will need to work on a function to check if the file system of the file and see whether it's ZFS. Let me know if you have any thoughts on this.
Luckily I don't have to locate any of the .zfs
filesβbut yes, I'm hoping to allow users using ZFS to provide a .zfs
file and for the function to be able to determine whether it is hidden. I have a lot to implement, but my current idea is to (using ccall
) construct an inode
so that I can convert it to a znode
(I don't know how else to create a znode
struct), from which I can get the attribute z_pflags
and it's simple enough from there. Unfortunately, this has not been easy so far, given limitations about what symbols I have access to (using your nm --dynamic
trick); hint: not all of the functions in ZFS's source I have access to...
Your idea of finding all the mount points might be good though. Do you think that would be easier than what I explained above? The other thing I have to consider is: are all subfiles/directories of this .zfs
directory also hidden? My intuition says yes (similar to how I have implemented packages/bundles in macOS).
Thank you for the useful information, that helps me to understand :)
from hiddenfiles.jl.
Thanks Alex, good to know about nm
.
nm
doesn't have struct namesnm
doesn't have anything defined as a preprocessor macro (e.g.f
in#define f(x) ...
)
Do you know how exactly to call structs (such as znode
) or definitions as a preprocessor macros in Julia (such as ITOZ
)? Or even how to call anything of the "D" type that nm
displays (i.e., D - A global symbol naming initialized data
). In particular, I am wondering if this one will help me:
00000000003b8010 D zfs_attr_table
Because I'm clearly doing it wrong!
julia> ccall((:zfs_attr_table, "libzpool"), Cvoid, ())
signal (11): Segmentation fault
in expression starting at REPL[1]:1
zfs_attr_table at /usr/lib/libzpool.so (unknown line)
# ...
Ultimately I need to find a way to create a znode
type in Julia, but I can't even get that working in C...
if you're doing this on FreeBSD, I recommend looking at the OpenZFS included in FreeBSD's monolithic source tree in case there are any differences compared to upstream.
Indeed, I'm developing on FreeBSD currently. I've been looking lots at the OpenZFS source on GitHub, but I haven't looked at in within the machine itself. I'll see if I can find it.
Also, do you know anything about how I might programmatically check if a file is stored on a ZFS partition? As this is no longer going to be a job for if Sys.isbsd()
, I'll need to find a way to check for existence of ZFS.
from hiddenfiles.jl.
If you define a Julia type with a layout compatible with the C struct, you can return objects with that type from
ccall
.
Thanks for your help with making structs from Julia. I hadn't figured that out yet, so I was just using Vectors, and indexing directly (instead of named fields). The problem with znode_t
is that I can't find it in any of the object files, so I guess I will have to figure out another way to get the znode
struct.
You'd have to reference whatever the macro expands to in your call on the Julia side
Ah, that makes sense, I figured that would be the case.
You need
cglobal
:
Oh neat, I didn't know about this function! Potentially stupid question, but how do you actually use the result? It's a pointer to some object in memory, but I'm not sure how exactly to make that into an array or whatever it should be.
do you know anything about how I might programmatically check if a file is stored on a ZFS partition?
Unfortunately I don't, sorry
π
No worries, I'll figure something out. You've been ever so helpful, thank you Alex
from hiddenfiles.jl.
Related Issues (17)
- Write macOS implementation of ishidden HOT 5
- Include option for checking if file is ignored
- Check if Windows implementation is correct HOT 3
- Implement ishidden on ZFS for BSD HOT 5
- Implement ishidden on ZFS for Linux HOT 1
- Consider storing stat results in a struct HOT 1
- Determine whether children of hidden directories or bundles should be hidden HOT 1
- Write tests/implement CI/CD
- TagBot trigger issue HOT 4
- Ensure directory references (. and ..) are hidden
- Write docstrings/documentation HOT 1
- Enchancement: use CFStringGetCharacters over iteration and CFStringGetCharacterAtIndex HOT 5
- Ensure string encoding for CFStrings work with non-UTF-8 pathnames HOT 2
- Refactor helper methods into subdirectory
- Consider using ObjectiveC.jl HOT 2
- Better error handling in inner functions HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from hiddenfiles.jl.