Instead of always using the temporary file /tmp/libupdatergtk.so generates a new name.

This solves a problem: if the file already existed and the current user
couldn't truncate it the auto update couldn't use the Gtk auto-updater.

In this commit it also deletes the file and avoids creating and closing
the file and opening again.

MD-20923
This commit is contained in:
Carles Pina 2014-11-19 16:09:50 +00:00
parent e2441e3e67
commit abe12806e5

View file

@ -30,27 +30,28 @@ UpdateDialogGtk* (*update_dialog_gtk_new)() = 0;
#define BIND_FUNCTION(library,function) \ #define BIND_FUNCTION(library,function) \
function = reinterpret_cast<TYPEOF(function)>(dlsym(library,#function)); function = reinterpret_cast<TYPEOF(function)>(dlsym(library,#function));
bool extractFileFromBinary(const char* path, const void* buffer, size_t length) #define MAX_FILE_PATH 4096
bool extractFileFromBinary(int fd, const void* buffer, size_t length)
{ {
int fd = open(path,O_CREAT | O_WRONLY | O_TRUNC,0755);
size_t count = write(fd,buffer,length); size_t count = write(fd,buffer,length);
if (fd < 0 || count < length)
{
if (fd >= 0)
{
close(fd); close(fd);
} return count >= length;
return false;
}
close(fd);
return true;
} }
UpdateDialog* UpdateDialogGtkFactory::createDialog() UpdateDialog* UpdateDialogGtkFactory::createDialog()
{ {
const char* libPath = "/tmp/libupdatergtk.so"; char* libPath = (char*)malloc(MAX_FILE_PATH);
snprintf(libPath, MAX_FILE_PATH, "/tmp/mendeley-libUpdaterGtk.so.XXXXXX");
if (!extractFileFromBinary(libPath,libupdatergtk_so,libupdatergtk_so_len)) int libFd = mkostemp(libPath, O_CREAT | O_WRONLY | O_TRUNC);
if (libFd == -1)
{
LOG(Warn,"Failed to create temporary file - " + std::string(strerror(errno)));
return 0;
}
if (!extractFileFromBinary(libFd,libupdatergtk_so,libupdatergtk_so_len))
{ {
LOG(Warn,"Failed to load the GTK UI library - " + std::string(strerror(errno))); LOG(Warn,"Failed to load the GTK UI library - " + std::string(strerror(errno)));
return 0; return 0;
@ -64,6 +65,7 @@ UpdateDialog* UpdateDialogGtkFactory::createDialog()
} }
BIND_FUNCTION(gtkLib,update_dialog_gtk_new); BIND_FUNCTION(gtkLib,update_dialog_gtk_new);
unlink(libPath);
return reinterpret_cast<UpdateDialog*>(update_dialog_gtk_new()); return reinterpret_cast<UpdateDialog*>(update_dialog_gtk_new());
} }