/*
* Copyright 2013 Canonical Ltd.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 3, as published
* by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranties of
* MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see .
*
* Authors:
* Ted Gould
*/
#include
#include
#include
#include
#include
#include "exec-line-exec-trace.h"
#include "helpers.h"
#include "ual-tracepoint.h"
int
main (int argc, char * argv[])
{
/* Make sure we have work to do */
/* This string is quoted using desktop file quoting:
http://standards.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#exec-variables */
const gchar * app_exec = g_getenv("APP_EXEC");
if (app_exec == NULL) {
/* There should be no reason for this, a g_error() so that it gets
picked up by Apport and we can track it */
g_error("No exec line given, nothing to do except fail");
return 1;
}
/* For the tracepoints */
const gchar * app_id = g_getenv("APP_ID");
ual_tracepoint(exec_start, app_id);
/* URIs */
const gchar * app_uris = g_getenv("APP_URIS");
/* Look to see if we have a directory defined that we
should be using for everything. If so, change to it
and add it to the path */
const gchar * appdir = g_getenv("APP_DIR");
if (appdir != NULL) {
if (g_chdir(appdir) != 0) {
g_warning("Unable to change directory to '%s'", appdir);
}
}
/* Protect against app directories that have ':' in them */
if (appdir != NULL && strchr(appdir, ':') == NULL) {
const gchar * path_path = g_getenv("PATH");
if (path_path != NULL && path_path[0] == '\0')
path_path = NULL;
gchar * path_libpath = NULL;
const gchar * path_joinable[4] = { 0 };
const gchar * lib_path = g_getenv("LD_LIBRARY_PATH");
if (lib_path != NULL && lib_path[0] == '\0')
lib_path = NULL;
gchar * lib_libpath = g_build_filename(appdir, "lib", NULL);
const gchar * lib_joinable[4] = { 0 };
const gchar * import_path = g_getenv("QML2_IMPORT_PATH");
if (import_path != NULL && import_path[0] == '\0')
import_path = NULL;
gchar * import_libpath = NULL;
const gchar * import_joinable[4] = { 0 };
/* If we've got an architecture set insert that into the
path before everything else */
const gchar * archdir = g_getenv("UBUNTU_APP_LAUNCH_ARCH");
if (archdir != NULL && strchr(archdir, ':') == NULL) {
path_libpath = g_build_filename(appdir, "lib", archdir, "bin", NULL);
import_libpath = g_build_filename(appdir, "lib", archdir, NULL);
path_joinable[0] = path_libpath;
path_joinable[1] = appdir;
path_joinable[2] = path_path;
lib_joinable[0] = import_libpath;
lib_joinable[1] = lib_libpath;
lib_joinable[2] = lib_path;
/* Need to check whether the original is NULL because we're
appending instead of prepending */
if (import_path == NULL) {
import_joinable[0] = import_libpath;
} else {
import_joinable[0] = import_path;
import_joinable[1] = import_libpath;
}
} else {
path_joinable[0] = appdir;
path_joinable[1] = path_path;
lib_joinable[0] = lib_libpath;
lib_joinable[1] = lib_path;
import_joinable[0] = import_path;
}
gchar * newpath = g_strjoinv(":", (gchar**)path_joinable);
g_setenv("PATH", newpath, TRUE);
g_free(path_libpath);
g_free(newpath);
gchar * newlib = g_strjoinv(":", (gchar**)lib_joinable);
g_setenv("LD_LIBRARY_PATH", newlib, TRUE);
g_free(lib_libpath);
g_free(newlib);
if (import_joinable[0] != NULL) {
gchar * newimport = g_strjoinv(":", (gchar**)import_joinable);
g_setenv("QML2_IMPORT_PATH", newimport, TRUE);
g_free(newimport);
}
g_free(import_libpath);
}
/* Parse the execiness of it all */
GArray * newargv = desktop_exec_parse(app_exec, app_uris);
if (newargv == NULL) {
g_warning("Unable to parse exec line '%s'", app_exec);
return 1;
}
/* Now exec */
gchar ** nargv = (gchar**)g_array_free(newargv, FALSE);
ual_tracepoint(exec_pre_exec, app_id);
int execret = execvp(nargv[0], nargv);
if (execret != 0) {
gchar * execprint = g_strjoinv(" ", nargv);
g_warning("Unable to exec '%s' in '%s': %s", execprint, appdir, strerror(errno));
g_free(execprint);
}
return execret;
}