summaryrefslogtreecommitdiff
path: root/src/libaudcore/vfs_local.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libaudcore/vfs_local.cc')
-rw-r--r--src/libaudcore/vfs_local.cc114
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;
+}