Commit cdf1d460 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

block: add read-only shared file mappings (fixes #17544)

parent 9dddafdc
......@@ -271,19 +271,24 @@ VLC_API block_t * block_shm_Alloc(void *addr, size_t length) VLC_USED VLC_MALLOC
* due to memory space constraints.
*
* @param fd file descriptor to load from
* @param write If true, request a read/write private mapping.
* If false, request a read-only potentially shared mapping.
*
* @return a new block with the file content at p_buffer, and file length at
* i_buffer (release it with block_Release()), or NULL upon error (see errno).
*/
VLC_API block_t *block_File(int fd, bool) VLC_USED VLC_MALLOC;
VLC_API block_t *block_File(int fd, bool write) VLC_USED VLC_MALLOC;
/**
* Maps a file in memory.
*
* Loads a file into a block of memory from a path to the file.
* See also block_File().
*
* @param write If true, request a read/write private mapping.
* If false, request a read-only potentially shared mapping.
*/
VLC_API block_t *block_FilePath(const char *, bool) VLC_USED VLC_MALLOC;
VLC_API block_t *block_FilePath(const char *, bool write) VLC_USED VLC_MALLOC;
static inline void block_Cleanup (void *block)
{
......
......@@ -208,7 +208,7 @@ static block_t *Shoot(demux_t *demux)
wl_display_roundtrip(sys->display);
wl_buffer_destroy(buffer);
block = block_File(fd);
block = block_File(fd, true);
if (block != NULL)
{
......
......@@ -329,7 +329,7 @@ static void DemuxFile (void *data)
demux_sys_t *sys = demux->p_sys;
/* Copy frame */
block_t *block = block_File (sys->fd);
block_t *block = block_File(sys->fd, true);
if (block == NULL)
return;
block->i_pts = block->i_dts = mdate ();
......
......@@ -643,7 +643,7 @@ static int OpenServer (vlc_tls_creds_t *crd, const char *cert, const char *key)
return VLC_ENOMEM;
}
block_t *certblock = block_FilePath (cert);
block_t *certblock = block_FilePath(cert, false);
if (certblock == NULL)
{
msg_Err (crd, "cannot read certificate chain from %s: %s", cert,
......@@ -651,7 +651,7 @@ static int OpenServer (vlc_tls_creds_t *crd, const char *cert, const char *key)
goto error;
}
block_t *keyblock = block_FilePath (key);
block_t *keyblock = block_FilePath(key, false);
if (keyblock == NULL)
{
msg_Err (crd, "cannot read private key from %s: %s", key,
......
......@@ -359,7 +359,7 @@ ssize_t pread (int fd, void *buf, size_t count, off_t offset)
}
#endif
block_t *block_File (int fd)
block_t *block_File(int fd, bool write)
{
size_t length;
struct stat st;
......@@ -396,9 +396,10 @@ block_t *block_File (int fd)
#ifdef HAVE_MMAP
if (length > 0)
{
void *addr;
int prot = PROT_READ | (write ? PROT_WRITE : 0);
int flags = write ? MAP_PRIVATE : MAP_SHARED;
void *addr = mmap(NULL, length, prot, flags, fd, 0);
addr = mmap (NULL, length, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
if (addr != MAP_FAILED)
return block_mmap_Alloc (addr, length);
}
......@@ -425,13 +426,15 @@ block_t *block_File (int fd)
return block;
}
block_t *block_FilePath (const char *path)
block_t *block_FilePath(const char *path, bool write)
{
/* NOTE: Writeable shared mappings are not supported here. So there are no
* needs to open the file for writing (even if the mapping is writable). */
int fd = vlc_open (path, O_RDONLY);
if (fd == -1)
return NULL;
block_t *block = block_File (fd);
block_t *block = block_File(fd, write);
vlc_close (fd);
return block;
}
......@@ -376,7 +376,7 @@ size_t CacheLoad(vlc_object_t *p_this, const char *dir, module_cache_t **r,
msg_Dbg( p_this, "loading plugins cache file %s", psz_filename );
block_t *file = block_FilePath(psz_filename);
block_t *file = block_FilePath(psz_filename, false);
if (file == NULL)
msg_Warn(p_this, "cannot read %s: %s", psz_filename,
vlc_strerror_c(errno));
......
......@@ -34,7 +34,7 @@ static const char text[] =
"This is a test!\n"
"This file can be deleted safely!\n";
static void test_block_File (void)
static void test_block_File(bool write)
{
FILE *stream;
int res;
......@@ -47,12 +47,14 @@ static void test_block_File (void)
res = fflush (stream);
assert (res != EOF);
block_t *block = block_File (fileno (stream));
block_t *block = block_File(fileno(stream), write);
fclose (stream);
assert (block != NULL);
assert (block->i_buffer == strlen (text));
assert (!memcmp (block->p_buffer, text, block->i_buffer));
if (write)
memset(block->p_buffer, 'A', block->i_buffer);
block_Release (block);
remove ("testfile.txt");
......@@ -86,7 +88,8 @@ static void test_block (void)
int main (void)
{
test_block_File ();
test_block_File(false);
test_block_File(true);
test_block ();
return 0;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment