[libdvdnav-devel] [PATCH 1/2] Use realpath() for symlink resolving

Floris Bos bos at je-eigen-domein.nl
Thu Dec 15 20:02:21 CET 2016


All major *NIX platforms support realpath() to get the absolute
path name nowadays, making it a better solution than the previous
chdir() -> getcwd() routine.

Signed-off-by: Floris Bos <bos at je-eigen-domein.nl>
---
 configure.ac     |  2 ++
 src/dvd_reader.c | 43 ++++++++++---------------------------------
 2 files changed, 12 insertions(+), 33 deletions(-)

diff --git a/configure.ac b/configure.ac
index 51da287..38810e9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -59,6 +59,8 @@ AC_CHECK_HEADERS_ONCE([sys/param.h limits.h dlfcn.h])
 AC_SYS_LARGEFILE
 AC_C_BIGENDIAN
 
+AC_CHECK_FUNCS(realpath)
+
 AS_CASE([$host],
   [*mingw32* | *cygwin*], [AC_CHECK_FUNCS(gettimeofday)])
 
diff --git a/src/dvd_reader.c b/src/dvd_reader.c
index 4e112d3..a9034de 100644
--- a/src/dvd_reader.c
+++ b/src/dvd_reader.c
@@ -25,11 +25,11 @@
 #include <sys/stat.h>       /* stat */
 #include <sys/time.h>       /* For the timing of dvdcss_title crack. */
 #include <fcntl.h>          /* open */
-#include <stdlib.h>         /* free */
+#include <stdlib.h>         /* free, realpath */
 #include <stdio.h>          /* fprintf */
 #include <errno.h>          /* errno, EIN* */
 #include <string.h>         /* memcpy, strlen */
-#include <unistd.h>         /* chdir, getcwd */
+#include <unistd.h>         /* chdir, getcwd, _POSIX_VERSION */
 #include <limits.h>         /* PATH_MAX */
 #include <dirent.h>         /* opendir, readdir */
 #include <ctype.h>          /* isalpha */
@@ -341,10 +341,10 @@ static dvd_reader_t *DVDOpenCommon( const char *ppath,
                                     dvd_reader_stream_cb *stream_cb )
 {
   struct stat fileinfo;
-  int ret, have_css, retval, cdir = -1;
+  int ret, have_css, cdir = -1;
   dvd_reader_t *ret_val = NULL;
   char *dev_name = NULL;
-  char *path = NULL, *new_path = NULL, *path_copy = NULL;
+  char *path = NULL, *path_copy = NULL;
 
 #if defined(_WIN32) || defined(__OS2__)
       int len;
@@ -425,37 +425,15 @@ static dvd_reader_t *DVDOpenCommon( const char *ppath,
     FILE *mntfile;
 #endif
 
+    /* Resolve any symlinks and get the absolute dir name on supported platforms. */
+#if defined(HAVE_REALPATH) && _POSIX_VERSION >= 200809L
+    path_copy = realpath( path, NULL );
+    if( !path_copy )
+      goto DVDOpen_error;
+#else
     /* XXX: We should scream real loud here. */
     if( !(path_copy = strdup( path ) ) )
       goto DVDOpen_error;
-
-#ifndef WIN32 /* don't have fchdir, and getcwd( NULL, ... ) is strange */
-              /* Also WIN32 does not have symlinks, so we don't need this bit of code. */
-
-    /* Resolve any symlinks and get the absolute dir name. */
-    {
-      if( ( cdir  = open( ".", O_RDONLY ) ) >= 0 ) {
-        if( chdir( path_copy ) == -1 ) {
-          goto DVDOpen_error;
-        }
-        new_path = malloc(PATH_MAX+1);
-        if(!new_path) {
-          goto DVDOpen_error;
-        }
-        if( getcwd( new_path, PATH_MAX ) == NULL ) {
-          goto DVDOpen_error;
-        }
-        retval = fchdir( cdir );
-        close( cdir );
-        cdir = -1;
-        if( retval == -1 ) {
-          goto DVDOpen_error;
-        }
-        free(path_copy);
-        path_copy = new_path;
-        new_path = NULL;
-      }
-    }
 #endif
 
     /**
@@ -610,7 +588,6 @@ DVDOpen_error:
   free( path_copy );
   if ( cdir >= 0 )
     close( cdir );
-  free( new_path );
   return NULL;
 }
 
-- 
2.7.4



More information about the libdvdnav-devel mailing list