vlc_getcwd: return current directory as UTF-8
authorRémi Denis-Courmont <remi@remlab.net>
Mon, 11 Jul 2011 15:39:59 +0000 (18:39 +0300)
committerRémi Denis-Courmont <remi@remlab.net>
Mon, 11 Jul 2011 15:47:43 +0000 (18:47 +0300)
include/vlc_fs.h
src/libvlccore.sym
src/posix/filesystem.c
src/win32/filesystem.c

index e3ab442..65cd4cb 100644 (file)
@@ -43,6 +43,7 @@ VLC_API int vlc_mkdir( const char *filename, mode_t mode );
 
 VLC_API int vlc_unlink( const char *filename );
 VLC_API int vlc_rename( const char *oldpath, const char *newpath );
+VLC_API char *vlc_getcwd( void ) VLC_USED;
 
 #if defined( WIN32 )
 # ifndef UNDER_CE
index 4d937b9..3b6de36 100644 (file)
@@ -467,6 +467,7 @@ vlc_stat
 vlc_strcasestr
 vlc_unlink
 vlc_rename
+vlc_getcwd
 vlc_dup
 vlc_pipe
 vlc_accept
index aadf35b..3347496 100644 (file)
@@ -307,6 +307,53 @@ error:
 }
 
 /**
+ * Determines the current working directory.
+ *
+ * @return the current working directory (must be free()'d)
+ *         or NULL on error
+ */
+char *vlc_getcwd (void)
+{
+    /* Try $PWD */
+    const char *pwd = getenv ("PWD");
+    if (pwd != NULL)
+    {
+        struct stat s1, s2;
+        /* Make sure $PWD is correct */
+        if (stat (pwd, &s1) == 0 && stat (".", &s2) == 0
+         && s1.st_dev == s2.st_dev && s1.st_ino == s2.st_ino)
+            return ToLocaleDup (pwd);
+    }
+
+    /* Otherwise iterate getcwd() until the buffer is big enough */
+    long path_max = pathconf (".", _PC_PATH_MAX);
+    size_t size = (path_max == -1 || path_max > 4096) ? 4096 : path_max;
+
+    for (;; size *= 2)
+    {
+        char *buf = malloc (size);
+        if (unlikely(buf == NULL))
+            break;
+
+        if (getcwd (buf, size) != NULL)
+#ifdef ASSUME_UTF8
+            return buf;
+#else
+        {
+            char *ret = ToLocaleDup (buf);
+            free (buf);
+            return ret; /* success */
+        }
+#endif
+        free (buf);
+
+        if (errno != ERANGE)
+            break;
+    }
+    return NULL;
+}
+
+/**
  * Duplicates a file descriptor. The new file descriptor has the close-on-exec
  * descriptor flag set.
  * @return a new file descriptor or -1
index dfcaee8..0ba5e0a 100644 (file)
@@ -108,6 +108,17 @@ int vlc_mkdir( const char *dirname, mode_t mode )
 #endif
 }
 
+char *vlc_getcwd (void)
+{
+    wchar_t *wdir = _wgetcwd (NULL, 0);
+    if (wdir == NULL)
+        return NULL;
+
+    char *dir = FromWide (wdir);
+    free (wdir);
+    return dir;
+}
+
 /* Under Windows, these wrappers return the list of drive letters
  * when called with an empty argument or just '\'. */
 typedef struct vlc_DIR