[vlc-devel] [PATCH] sout: file: truncate path if too long

Thomas Guillem thomas at gllm.fr
Mon Dec 16 15:57:59 CET 2019


This fixes sout chain fail when the input path/url was too long. This can
easily happen when the source is a network url that can be longer than local
pathes.
---
 modules/access_output/file.c | 67 ++++++++++++++++++++++++++++++------
 1 file changed, 57 insertions(+), 10 deletions(-)

diff --git a/modules/access_output/file.c b/modules/access_output/file.c
index fbefce0be8..57d83636b9 100644
--- a/modules/access_output/file.c
+++ b/modules/access_output/file.c
@@ -37,6 +37,8 @@
 #include <errno.h>
 #include <sys/stat.h>
 #include <unistd.h>
+#include <limits.h>
+#include <string.h>
 #ifdef __OS2__
 #   include <io.h>      /* setmode() */
 #endif
@@ -299,24 +301,69 @@ static int Open( vlc_object_t *p_this )
         if (var_GetBool (p_access, SOUT_CFG_PREFIX"sync"))
             flags |= O_SYNC;
 #endif
-        do
+
+        for (;;)
         {
             fd = vlc_open (path, flags, 0666);
+            fprintf(stderr, "open: %d\n", fd);
             if (fd != -1)
                 break;
             if (fd == -1)
                 msg_Err (p_access, "cannot create %s: %s", path,
                          vlc_strerror_c(errno));
-            if (overwrite || errno != EEXIST)
-                break;
-            flags &= ~O_EXCL;
+
+            if (errno == ENAMETOOLONG)
+            {
+#ifndef NAME_MAX
+ #ifdef MAX_PATH
+  #define NAME_MAX MAX_PATH /* win32 */
+ #else
+  #define NAME_MAX 256
+ #endif
+#endif
+                /* The path need to be truncated */
+                size_t path_len = strlen(path);
+
+                if (unlikely(path_len <= NAME_MAX))
+                    break;
+
+                /* Allocate the buf if needed since p_access->psz_path is const */
+                if (path == p_access->psz_path)
+                {
+                    buf = strdup(path);
+                    if (!buf)
+                        break;
+                    path = buf;
+                }
+
+                /* Don't loose the extension if any */
+                const char *ext = strrchr(path, '.');
+                size_t ext_len = ext ? strlen(ext) : 0;
+                if (ext && ext_len <= 4)
+                    strcpy(&buf[NAME_MAX - ext_len - 1], ext);
+                else
+                    buf[NAME_MAX] = 0;
+
+                continue;
+            }
+
+            if (!overwrite && errno == EEXIST)
+            {
+                int ret =
+                    vlc_dialog_wait_question (p_access, VLC_DIALOG_QUESTION_NORMAL,
+                                              _("Keep existing file"),
+                                              _("Overwrite"), NULL, path,
+                                              _("The output file already exists. "
+                                              "If recording continues, the file will be "
+                                              "overridden and its content will be lost."));
+                if (ret == 1) /* Overwrite */
+                {
+                    flags &= ~O_EXCL;
+                    continue;
+                }
+            }
+            break;
         }
-        while (vlc_dialog_wait_question (p_access, VLC_DIALOG_QUESTION_NORMAL,
-                                         _("Keep existing file"),
-                                         _("Overwrite"), NULL, path,
-                                         _("The output file already exists. "
-                                         "If recording continues, the file will be "
-                                         "overridden and its content will be lost.")) == 1);
         free (buf);
         if (fd == -1)
             return VLC_EGENERIC;
-- 
2.20.1



More information about the vlc-devel mailing list