[vlc-commits] [Git][videolan/vlc][master] samba: use the new API

Jean-Baptiste Kempf (@jbk) gitlab at videolan.org
Fri Dec 17 06:45:44 UTC 2021



Jean-Baptiste Kempf pushed to branch master at VideoLAN / VLC


Commits:
2a6a684d by Thomas Guillem at 2021-12-17T06:24:29+00:00
samba: use the new API

And fix potential data races, that could have become criticial with the
new medialibary (more than one samba access in //). Indeed, the SMBCCTX
and SMBCFILE were stored statically and fetch from an unique fd without
any lock mechanism.

- - - - -


1 changed file:

- modules/access/samba.c


Changes:

=====================================
modules/access/samba.c
=====================================
@@ -40,7 +40,23 @@
 
 typedef struct
 {
-    int i_smb;
+    SMBCCTX *ctx;
+    SMBCFILE *file;
+
+    union
+    {
+        struct {
+            smbc_close_fn close;
+            smbc_read_fn read;
+            smbc_lseek_fn lseek;
+        } filevt;
+        struct {
+            smbc_closedir_fn closedir;
+            smbc_stat_fn stat;
+            smbc_readdir_fn readdir;
+        } dirvt;
+    };
+
     uint64_t size;
     vlc_url_t url;
 } access_sys_t;
@@ -83,7 +99,7 @@ static int Seek( stream_t *p_access, uint64_t i_pos )
 
     msg_Dbg( p_access, "seeking to %"PRId64, i_pos );
 
-    i_ret = smbc_lseek( p_sys->i_smb, i_pos, SEEK_SET );
+    i_ret = p_sys->filevt.lseek( p_sys->ctx, p_sys->file, i_pos, SEEK_SET );
     if( i_ret == -1 )
     {
         msg_Err( p_access, "seek failed (%s)", vlc_strerror_c(errno) );
@@ -105,13 +121,11 @@ static ssize_t Read( stream_t *p_access, void *p_buffer, size_t i_len )
      * than this limit will likely result on a ECONNABORTED
      * (STATUS_CONNECTION_ABORTED) error. Since this value can be lowered by
      * the server, let decrease this limit (/8) to have more chance to get a
-     * working limit on our side.
-     * XXX: There is no way to retrieve this value when using the old smbc_*
-     * interface. */
+     * working limit on our side. */
     if( i_len > (1024 << 10) ) /* 8MB / 8 = 1MB */
         i_len = 1024 << 10;
 
-    i_read = smbc_read( p_sys->i_smb, p_buffer, i_len );
+    i_read = p_sys->filevt.read( p_sys->ctx, p_sys->file, p_buffer, i_len );
     if( i_read < 0 )
     {
         msg_Err( p_access, "read failed (%s)", vlc_strerror_c(errno) );
@@ -134,7 +148,7 @@ static int DirRead (stream_t *p_access, input_item_node_t *p_node )
 
     struct smbc_dirent *p_entry;
 
-    while( i_ret == VLC_SUCCESS && ( p_entry = smbc_readdir( p_sys->i_smb ) ) )
+    while( i_ret == VLC_SUCCESS && ( p_entry = p_sys->dirvt.readdir( p_sys->ctx, p_sys->file ) ) )
     {
         const char *psz_server = p_sys->url.psz_host;
         const char *psz_path = p_sys->url.psz_path;
@@ -180,7 +194,7 @@ static int DirRead (stream_t *p_access, input_item_node_t *p_node )
             break;
         }
         struct stat st;
-        smbc_stat(uri, &st);
+        p_sys->dirvt.stat(p_sys->ctx, uri, &st);
 
         input_item_t *p_item;
         free(psz_encoded_name);
@@ -260,17 +274,26 @@ static int Open(vlc_object_t *obj)
     vlc_url_t url;
     vlc_credential credential;
     char *psz_decoded_path = NULL, *uri, *psz_var_domain = NULL;
-    int fd;
     uint64_t size;
     bool is_dir;
+    int ret = VLC_EGENERIC;
+    SMBCFILE *file = NULL;
+    SMBCCTX *ctx;
 
-    if (smbc_init(smb_auth, 0))
-        return VLC_EGENERIC;
+    ctx = smbc_new_context();
+    if (ctx == NULL)
+        return VLC_ENOMEM;
+
+    smbc_setDebug(ctx, 0);
+    smbc_setFunctionAuthData(ctx, smb_auth);
+
+    if (!smbc_init_context(ctx))
+        goto error;
 
     if (vlc_UrlParseFixup(&url, access->psz_url) != 0)
     {
         vlc_UrlClean(&url);
-        return VLC_EGENERIC;
+        goto error;
     }
 
     if (url.psz_path != NULL)
@@ -279,7 +302,7 @@ static int Open(vlc_object_t *obj)
         if (psz_decoded_path == NULL)
         {
             vlc_UrlClean(&url);
-            return VLC_EGENERIC;
+            goto error;
         }
     }
 
@@ -288,6 +311,9 @@ static int Open(vlc_object_t *obj)
     credential.psz_realm = psz_var_domain;
     vlc_credential_get(&credential, access, "smb-user", "smb-pwd", NULL, NULL);
 
+    smbc_stat_fn stat_fn = smbc_getFunctionStat(ctx);
+    assert(stat_fn);
+
     for (;;)
     {
         struct stat st;
@@ -301,10 +327,12 @@ static int Open(vlc_object_t *obj)
             free(psz_var_domain);
             free(psz_decoded_path);
             vlc_UrlClean(&url);
-            return VLC_ENOMEM;
+            ret = VLC_ENOMEM;
+            goto error;
         }
 
-        if (smbc_stat(uri, &st) == 0)
+
+        if (stat_fn(ctx, uri, &st) == 0)
         {
             is_dir = S_ISDIR(st.st_mode) != 0;
             size = st.st_size;
@@ -343,34 +371,58 @@ static int Open(vlc_object_t *obj)
 
     if (is_dir)
     {
+        smbc_opendir_fn opendir_fn = smbc_getFunctionOpendir(ctx);
+        assert(opendir_fn);
+
+        sys->dirvt.closedir = smbc_getFunctionClosedir(ctx);
+        assert(sys->dirvt.closedir);
+        sys->dirvt.readdir = smbc_getFunctionReaddir(ctx);
+        assert(sys->dirvt.readdir);
+        sys->dirvt.stat = stat_fn;
+
         sys->url = url;
         access->pf_readdir = DirRead;
         access->pf_control = access_vaDirectoryControlHelper;
-        fd = smbc_opendir(uri);
-        if (fd < 0)
+        file = opendir_fn(ctx, uri);
+        if (file == NULL)
             vlc_UrlClean(&sys->url);
     }
     else
     {
+        smbc_open_fn open_fn = smbc_getFunctionOpen(ctx);
+        assert(open_fn);
+
+        sys->filevt.close = smbc_getFunctionClose(ctx);
+        assert(sys->filevt.close);
+        sys->filevt.read = smbc_getFunctionRead(ctx);
+        assert(sys->filevt.read);
+        sys->filevt.lseek = smbc_getFunctionLseek(ctx);
+        assert(sys->filevt.lseek);
+
         access->pf_read = Read;
         access->pf_control = Control;
         access->pf_seek = Seek;
-        fd = smbc_open(uri, O_RDONLY, 0);
+        file = open_fn(ctx, uri, O_RDONLY, 0);
         vlc_UrlClean(&url);
     }
     free(uri);
 
-    if (fd < 0)
+    if (file == NULL)
     {
         msg_Err(obj, "cannot open %s: %s",
                 access->psz_location, vlc_strerror_c(errno));
-        return VLC_EGENERIC;
+        goto error;
     }
 
     sys->size = size;
-    sys->i_smb = fd;
+    sys->ctx = ctx;
+    sys->file = file;
 
     return VLC_SUCCESS;
+
+error:
+    smbc_free_context(ctx, 1);
+    return ret;
 }
 
 static void Close(vlc_object_t *obj)
@@ -381,9 +433,11 @@ static void Close(vlc_object_t *obj)
     vlc_UrlClean(&sys->url);
 
     if (access->pf_readdir != NULL)
-        smbc_closedir(sys->i_smb);
+        sys->dirvt.closedir(sys->ctx, sys->file);
     else
-        smbc_close(sys->i_smb);
+        sys->filevt.close(sys->ctx, sys->file);
+
+    smbc_free_context(sys->ctx, 1);
 }
 
 vlc_module_begin()



View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/2a6a684da4db88cdb92fdcecb1ffb43b315f4ae5

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/2a6a684da4db88cdb92fdcecb1ffb43b315f4ae5
You're receiving this email because of your account on code.videolan.org.




More information about the vlc-commits mailing list