[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