Skip to content

Commit

Permalink
[DROID] Read /proc/mounts in one go to avoid race.
Browse files Browse the repository at this point in the history
/proc/mounts is only guaranteed atomic for the current read operation.
  • Loading branch information
t-nelson committed Feb 25, 2014
1 parent 6abd677 commit de12a4c
Showing 1 changed file with 54 additions and 8 deletions.
62 changes: 54 additions & 8 deletions xbmc/storage/android/AndroidStorageProvider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
#include "utils/RegExp.h"
#include "utils/StringUtils.h"
#include "utils/URIUtils.h"
#include <cstdio>
#include <cstring>
#include <cstdlib>

CAndroidStorageProvider::CAndroidStorageProvider()
{
Expand Down Expand Up @@ -95,16 +98,59 @@ void CAndroidStorageProvider::GetLocalDrives(VECSOURCES &localDrives)
void CAndroidStorageProvider::GetRemovableDrives(VECSOURCES &removableDrives)
{
// mounted usb disks
char* buf = NULL;
FILE* pipe;
std::vector<CStdString> result;
CRegExp reMount;
CRegExp reMount;
reMount.RegComp("^(.+?)\\s+(.+?)\\s+(.+?)\\s");
char line[1024];

FILE* pipe = fopen("/proc/mounts", "r");
/* /proc/mounts is only guaranteed atomic for the current read
* operation, so we need to read it all at once.
*/
if ((pipe = fopen("/proc/mounts", "r")))
{
char* new_buf;
size_t buf_len = 4096;

while ((new_buf = (char*)realloc(buf, buf_len * sizeof(char))))
{
size_t nread;

if (pipe)
buf = new_buf;
nread = fread(buf, sizeof(char), buf_len, pipe);

if (nread == buf_len)
{
rewind(pipe);
buf_len *= 2;
}
else
{
buf[nread] = '\0';
if (!feof(pipe))
new_buf = NULL;
break;
}
}

if (!new_buf)
{
free(buf);
buf = NULL;
}
fclose(pipe);
}
else
CLog::Log(LOGERROR, "Cannot read mount points");

if (buf)
{
while (fgets(line, sizeof(line) - 1, pipe))
char* line;
char* saveptr = NULL;

line = strtok_r(buf, "\n", &saveptr);

while (line)
{
if (reMount.RegFind(line) != -1)
{
Expand Down Expand Up @@ -132,10 +178,10 @@ void CAndroidStorageProvider::GetRemovableDrives(VECSOURCES &removableDrives)
if(accepted)
result.push_back(mount);
}
line = strtok_r(NULL, "\n", &saveptr);
}
fclose(pipe);
} else
CLog::Log(LOGERROR, "Cannot read mount points");
free(buf);
}

for (unsigned int i = 0; i < result.size(); i++)
{
Expand Down

0 comments on commit de12a4c

Please sign in to comment.