diff --git a/src/dlangui/core/files.d b/src/dlangui/core/files.d index b4b0aedb..1ec800a0 100644 --- a/src/dlangui/core/files.d +++ b/src/dlangui/core/files.d @@ -115,8 +115,72 @@ struct RootEntry { return path; } +version(OSX) {} else version(Posix) +{ + private bool isSpecialFileSystem(const(char)[] dir, const(char)[] type) + { + import std.string : startsWith; + if (dir.startsWith("/dev") || dir.startsWith("/proc") || dir.startsWith("/sys") || + dir.startsWith("/var/run") || dir.startsWith("/var/lock")) + { + return true; + } + + if (type == "tmpfs" || type == "rootfs" || type == "rpc_pipefs") { + return true; + } + return false; + } +} + +version(FreeBSD) +{ +private: + import core.sys.posix.sys.types; + + enum MFSNAMELEN = 16; /* length of type name including null */ + enum MNAMELEN = 88; /* size of on/from name bufs */ + enum STATFS_VERSION = 0x20030518; /* current version number */ + + struct fsid_t + { + int[2] val; + } + + struct statfs { + uint f_version; /* structure version number */ + uint f_type; /* type of filesystem */ + ulong f_flags; /* copy of mount exported flags */ + ulong f_bsize; /* filesystem fragment size */ + ulong f_iosize; /* optimal transfer block size */ + ulong f_blocks; /* total data blocks in filesystem */ + ulong f_bfree; /* free blocks in filesystem */ + long f_bavail; /* free blocks avail to non-superuser */ + ulong f_files; /* total file nodes in filesystem */ + long f_ffree; /* free nodes avail to non-superuser */ + ulong f_syncwrites; /* count of sync writes since mount */ + ulong f_asyncwrites; /* count of async writes since mount */ + ulong f_syncreads; /* count of sync reads since mount */ + ulong f_asyncreads; /* count of async reads since mount */ + ulong[10] f_spare; /* unused spare */ + uint f_namemax; /* maximum filename length */ + uid_t f_owner; /* user that mounted the filesystem */ + fsid_t f_fsid; /* filesystem id */ + char[80] f_charspare; /* spare string space */ + char[MFSNAMELEN] f_fstypename; /* filesystem type name */ + char[MNAMELEN] f_mntfromname; /* mounted filesystem */ + char[MNAMELEN] f_mntonname; /* directory on which mounted */ + }; + + extern(C) @nogc nothrow + { + int getmntinfo(statfs **mntbufp, int flags); + } +} + version(linux) { +private: import core.stdc.stdio : FILE; struct mntent { @@ -146,21 +210,6 @@ version(linux) .replace("\\x5c", "\\") .replace("\\xA", " "); //actually newline } - - bool isSpecialFileSystem(const(char)[] dir, const(char)[] type) - { - import std.string : startsWith; - if (dir.startsWith("/dev") || dir.startsWith("/proc") || dir.startsWith("/sys") || - dir.startsWith("/var/run") || dir.startsWith("/var/lock")) - { - return true; - } - - if (type == "tmpfs" || type == "rootfs" || type == "rpc_pipefs") { - return true; - } - return false; - } } /// returns array of system root entries @@ -217,6 +266,30 @@ version(linux) } } + version(FreeBSD) { + import std.string : fromStringz; + import std.format : format; + + statfs* mntbufsPtr; + int mntbufsLen = getmntinfo(&mntbufsPtr, 0); + if (mntbufsLen) { + auto mntbufs = mntbufsPtr[0..mntbufsLen]; + + foreach(buf; mntbufs) { + auto type = fromStringz(buf.f_fstypename.ptr); + auto fsName = fromStringz(buf.f_mntfromname.ptr); + auto mountDir = fromStringz(buf.f_mntonname.ptr); + + if (mountDir == "/" || isSpecialFileSystem(mountDir, type)) { + continue; + } + + string label = format("%s volume", type); + res ~= RootEntry(RootEntryType.FIXED, mountDir.idup, label.toUTF32); + } + } + } + version (Windows) { import win32.windows; uint mask = GetLogicalDrives();