diff options
Diffstat (limited to 'src/libaudcore/vfs_local.cc')
-rw-r--r-- | src/libaudcore/vfs_local.cc | 114 |
1 files changed, 106 insertions, 8 deletions
diff --git a/src/libaudcore/vfs_local.cc b/src/libaudcore/vfs_local.cc index c1b10e5..7af685f 100644 --- a/src/libaudcore/vfs_local.cc +++ b/src/libaudcore/vfs_local.cc @@ -17,15 +17,16 @@ * the use of this software. */ -#define WANT_VFS_STDIO_COMPAT -#include "vfs_local.h" - #include <errno.h> #include <string.h> #include <unistd.h> #include <glib/gstdio.h> +/* needs to be after system headers for #undef's to take effect */ +#define WANT_VFS_STDIO_COMPAT +#include "vfs_local.h" + #include "audstrings.h" #include "i18n.h" #include "runtime.h" @@ -75,7 +76,7 @@ private: LocalOp m_last_op; }; -VFSImpl * vfs_local_fopen (const char * uri, const char * mode, String & error) +VFSImpl * LocalTransport::fopen (const char * uri, const char * mode, String & error) { StringBuf path = uri_to_filename (uri); @@ -97,7 +98,7 @@ VFSImpl * vfs_local_fopen (const char * uri, const char * mode, String & error) StringBuf mode2 = str_concat ({mode, suffix}); - FILE * stream = g_fopen (path, mode2); + FILE * stream = ::g_fopen (path, mode2); if (! stream) { @@ -108,9 +109,9 @@ VFSImpl * vfs_local_fopen (const char * uri, const char * mode, String & error) * 2) UTF-8 filesystem mounted on legacy system */ if (errsave == ENOENT) { - StringBuf path2 = str_to_utf8 (uri_to_filename (uri, false)); + StringBuf path2 = uri_to_filename (uri, false); if (path2 && strcmp (path, path2)) - stream = g_fopen (path2, mode2); + stream = ::g_fopen (path2, mode2); } if (! stream) @@ -124,7 +125,7 @@ VFSImpl * vfs_local_fopen (const char * uri, const char * mode, String & error) return new LocalFile (path, stream); } -VFSImpl * vfs_stdin_fopen (const char * mode, String & error) +VFSImpl * StdinTransport::fopen (const char * uri, const char * mode, String & error) { if (mode[0] != 'r' || strchr (mode, '+')) { @@ -135,6 +136,21 @@ VFSImpl * vfs_stdin_fopen (const char * mode, String & error) return new LocalFile ("(stdin)", stdin); } +VFSImpl * vfs_tmpfile (String & error) +{ + FILE * stream = tmpfile (); + + if (! stream) + { + int errsave = errno; + perror ("(tmpfile)"); + error = String (strerror (errsave)); + return nullptr; + } + + return new LocalFile ("(tmpfile)", stream); +} + LocalFile::~LocalFile () { // do not close stdin @@ -305,3 +321,85 @@ ERR: perror (m_path); return -1; } + +VFSFileTest LocalTransport::test_file (const char * uri, VFSFileTest test, String & error) +{ + StringBuf path = uri_to_filename (uri); + if (! path) + { + error = String (_("Invalid file name")); + return VFSFileTest (test & VFS_NO_ACCESS); + } + + int passed = 0; + bool need_stat = true; + GStatBuf st; + +#ifdef S_ISLNK + if (test & VFS_IS_SYMLINK) + { + if (g_lstat (path, & st) < 0) + { + error = String (strerror (errno)); + passed |= VFS_NO_ACCESS; + goto out; + } + + if (S_ISLNK (st.st_mode)) + passed |= VFS_IS_SYMLINK; + else + need_stat = false; + } +#endif + + if (test & (VFS_IS_REGULAR | VFS_IS_DIR | VFS_IS_EXECUTABLE | VFS_EXISTS | VFS_NO_ACCESS)) + { + if (need_stat && g_stat (path, & st) < 0) + { + error = String (strerror (errno)); + passed |= VFS_NO_ACCESS; + goto out; + } + + if (S_ISREG (st.st_mode)) + passed |= VFS_IS_REGULAR; + if (S_ISDIR (st.st_mode)) + passed |= VFS_IS_DIR; + if (st.st_mode & S_IXUSR) + passed |= VFS_IS_EXECUTABLE; + + passed |= VFS_EXISTS; + } + +out: + return VFSFileTest (test & passed); +} + +Index<String> LocalTransport::read_folder (const char * uri, String & error) +{ + Index<String> entries; + + StringBuf path = uri_to_filename (uri); + if (! path) + { + error = String (_("Invalid file name")); + return entries; + } + + GError * gerr = nullptr; + GDir * folder = g_dir_open (path, 0, & gerr); + if (! folder) + { + error = String (gerr->message); + g_error_free (gerr); + return entries; + } + + const char * name; + while ((name = g_dir_read_name (folder))) + entries.append (String (filename_to_uri (filename_build ({path, name})))); + + g_dir_close (folder); + + return entries; +} |