diff --git a/src/bin/e_exec.c b/src/bin/e_exec.c
index d8b275332..54d87b129 100644
--- a/src/bin/e_exec.c
+++ b/src/bin/e_exec.c
@@ -2,3 +2,692 @@
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
*/
#include "e.h"
+
+#define MAX_OUTPUT_CHARACTERS 5000
+
+/* TODO:
+ * - Clear e_exec_instances on shutdown
+ * - Clear e_exec_start_pending on shutdown
+ * - Create border add handler
+ */
+
+typedef struct _E_Exec_Launch E_Exec_Launch;
+typedef struct _E_Exec_Instance E_Exec_Instance;
+
+struct _E_Exec_Launch
+{
+ E_Zone *zone;
+ const char *launch_method;
+};
+
+struct _E_Exec_Instance
+{
+ Efreet_Desktop *desktop;
+ Ecore_Exe *exe;
+ int launch_id;
+ double launch_time;
+ Ecore_Timer *expire_timer;
+};
+
+struct _E_Config_Dialog_Data
+{
+ Efreet_Desktop *desktop;
+ char *exec;
+
+ Ecore_Exe_Event_Del event;
+ Ecore_Exe_Event_Data *error;
+ Ecore_Exe_Event_Data *read;
+
+ char *label;
+ char *exit;
+ char *signal;
+};
+
+static void _e_exec_cb_exec(void *data, Efreet_Desktop *desktop, char *exec, int remaining);
+static int _e_exec_cb_expire_timer(void *data);
+static int _e_exec_cb_exit(void *data, int type, void *event);
+
+static void _e_exec_error_dialog(Efreet_Desktop *desktop, const char *exec, Ecore_Exe_Event_Del *event, Ecore_Exe_Event_Data *error, Ecore_Exe_Event_Data *read);
+static void _fill_data(E_Config_Dialog_Data *cfdata);
+static void *_create_data(E_Config_Dialog *cfd);
+static void _free_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+static Evas_Object *_basic_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata);
+static Evas_Object *_advanced_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata);
+static Evas_Object *_dialog_scrolltext_create(Evas *evas, char *title, Ecore_Exe_Event_Data_Line *lines);
+static void _dialog_save_cb(void *data, void *data2);
+
+static Evas_List *e_exec_start_pending = NULL;
+static Evas_Hash *e_exec_instances = NULL;
+static int startup_id = 0;
+
+static Ecore_Event_Handler *_e_exec_exit_handler = NULL;
+static Ecore_Event_Handler *_e_exec_border_add_handler = NULL;
+
+EAPI int
+e_exec_init(void)
+{
+ _e_exec_exit_handler =
+ ecore_event_handler_add(ECORE_EXE_EVENT_DEL, _e_exec_cb_exit, NULL);
+#if 0
+ _e_exec_border_add_handler =
+ ecore_event_handler_add(E_EVENT_BORDER_ADD, _e_exec_cb_event_border_add, NULL);
+#endif
+ return 1;
+}
+
+EAPI int
+e_exec_shutdown(void)
+{
+ char buf[256];
+
+ snprintf(buf, sizeof(buf), "%i", startup_id);
+ e_util_env_set("E_STARTUP_ID", buf);
+
+ if (_e_exec_exit_handler) ecore_event_handler_del(_e_exec_exit_handler);
+ if (_e_exec_border_add_handler) ecore_event_handler_del(_e_exec_border_add_handler);
+ return 1;
+}
+
+EAPI int
+e_exec(E_Zone *zone, Efreet_Desktop *desktop, const char *exec,
+ Ecore_List *files, const char *launch_method)
+{
+ E_Exec_Launch *launch;
+
+ if ((!desktop) && (!exec)) return 0;
+ launch = E_NEW(E_Exec_Launch, 1);
+ if (!launch) return 0;
+ if (zone)
+ {
+ launch->zone = zone;
+ e_object_ref(E_OBJECT(launch->zone));
+ }
+ if (launch_method) launch->launch_method = evas_stringshare_add(launch_method);
+
+ if (desktop)
+ {
+ if (exec)
+ _e_exec_cb_exec(launch, NULL, strdup(exec), 0);
+ else
+ efreet_desktop_command_get(desktop, files, _e_exec_cb_exec, launch);
+ }
+ else
+ {
+ _e_exec_cb_exec(launch, NULL, strdup(exec), 0);
+ }
+ return 1;
+}
+
+static void
+_e_exec_cb_exec(void *data, Efreet_Desktop *desktop, char *exec, int remaining)
+{
+ E_Exec_Instance *inst = NULL;
+ E_Exec_Launch *launch;
+ Ecore_Exe *exe;
+ char *penv_display;
+ char buf[4096];
+
+ launch = data;
+ if (desktop)
+ {
+ inst = E_NEW(E_Exec_Instance, 1);
+ if (!inst) return;
+ }
+
+ if (startup_id == 0)
+ {
+ const char *p;
+ p = getenv("E_STARTUP_ID");
+ if (p) startup_id = atoi(p);
+ e_util_env_set("E_STARTUP_ID", NULL);
+ }
+ if (++startup_id < 1) startup_id = 1;
+ /* save previous env vars we need to save */
+ penv_display = getenv("DISPLAY");
+ if (penv_display) penv_display = strdup(penv_display);
+ if ((penv_display) && (launch->zone))
+ {
+ const char *p1, *p2;
+ char buf2[32];
+ int head;
+
+ head = launch->zone->container->manager->num;
+
+ /* set env vars */
+ p1 = strrchr(penv_display, ':');
+ p2 = strrchr(penv_display, '.');
+ if ((p1) && (p2) && (p2 > p1)) /* "blah:x.y" */
+ {
+ /* yes it could overflow... but who will overflow DISPLAY eh? why? to
+ * "exploit" your own applications running as you?
+ */
+ strcpy(buf, penv_display);
+ buf[p2 - penv_display + 1] = 0;
+ snprintf(buf2, sizeof(buf2), "%i", head);
+ strcat(buf, buf2);
+ }
+ else if (p1) /* "blah:x */
+ {
+ strcpy(buf, penv_display);
+ snprintf(buf2, sizeof(buf2), ".%i", head);
+ strcat(buf, buf2);
+ }
+ else
+ strcpy(buf, penv_display);
+ e_util_env_set("DISPLAY", buf);
+ }
+ snprintf(buf, sizeof(buf), "E_START|%i", startup_id);
+ e_util_env_set("DESKTOP_STARTUP_ID", buf);
+
+ e_util_library_path_strip();
+ exe = ecore_exe_pipe_run(exec,
+ ECORE_EXE_PIPE_AUTO | ECORE_EXE_PIPE_READ | ECORE_EXE_PIPE_ERROR |
+ ECORE_EXE_PIPE_READ_LINE_BUFFERED | ECORE_EXE_PIPE_ERROR_LINE_BUFFERED,
+ inst);
+ e_util_library_path_restore();
+ if (penv_display)
+ {
+ e_util_env_set("DISPLAY", penv_display);
+ free(penv_display);
+ }
+ if (!exe)
+ {
+ E_FREE(inst);
+ e_util_dialog_show(_("Run Error"),
+ _("Enlightenment was unable to fork a child process:
"
+ "
"
+ "%s
"),
+ exec);
+ return;
+ }
+ /* reset env vars */
+ if (launch->launch_method) e_exehist_add(launch->launch_method, exec);
+ free(exec);
+ /* 20 lines at start and end, 20x100 limit on bytes at each end. */
+ ecore_exe_auto_limits_set(exe, 2000, 2000, 20, 20);
+ ecore_exe_tag_set(exe, "E/exec");
+
+ if (desktop)
+ {
+ Evas_List *l;
+
+ inst->desktop = desktop;
+ inst->exe = exe;
+ inst->launch_id = startup_id;
+ inst->launch_time = ecore_time_get();
+ inst->expire_timer = ecore_timer_add(10.0, _e_exec_cb_expire_timer, inst);
+
+ l = evas_hash_find(e_exec_instances, desktop->orig_path);
+ l = evas_list_append(l, inst);
+ evas_hash_direct_add(e_exec_instances, desktop->orig_path, l);
+ e_exec_start_pending = evas_list_append(e_exec_start_pending, desktop);
+ }
+ else
+ ecore_exe_free(exe);
+ if (!remaining)
+ {
+ if (launch->launch_method) evas_stringshare_del(launch->launch_method);
+ if (launch->zone) e_object_unref(E_OBJECT(launch->zone));
+ free(launch);
+ }
+}
+
+static int
+_e_exec_cb_expire_timer(void *data)
+{
+ E_Exec_Instance *inst;
+
+ inst = data;
+ e_exec_start_pending = evas_list_remove(e_exec_start_pending, inst->desktop);
+ inst->expire_timer = NULL;
+ return 0;
+}
+
+static int
+_e_exec_cb_exit(void *data, int type, void *event)
+{
+ Evas_List *instances;
+ Ecore_Exe_Event_Del *ev;
+ E_Exec_Instance *inst;
+
+ ev = event;
+ if (!ev->exe) return 1;
+ if (!(ecore_exe_tag_get(ev->exe) &&
+ (!strcmp(ecore_exe_tag_get(ev->exe), "E/exec")))) return 1;
+ inst = ecore_exe_data_get(ev->exe);
+ if (!inst) return 1;
+
+ /* /bin/sh uses this if cmd not found */
+ if ((ev->exited) &&
+ ((ev->exit_code == 127) || (ev->exit_code == 255)))
+ {
+ E_Dialog *dia;
+
+ dia = e_dialog_new(e_container_current_get(e_manager_current_get()),
+ "E", "_e_exec_run_error_dialog");
+ if (dia)
+ {
+ char buf[4096];
+
+ e_dialog_title_set(dia, _("Application run error"));
+ snprintf(buf, sizeof(buf),
+ _("Enlightenment was unable to run the application:
"
+ "
"
+ "%s
"
+ "
"
+ "The application failed to start."),
+ ecore_exe_cmd_get(ev->exe));
+ e_dialog_text_set(dia, buf);
+ e_dialog_button_add(dia, _("OK"), NULL, NULL, NULL);
+ e_dialog_button_focus_num(dia, 1);
+ e_win_centered_set(dia->win, 1);
+ e_dialog_show(dia);
+ }
+ }
+ /* Let's hope that everything returns this properly. */
+ else if (!((ev->exited) && (ev->exit_code == EXIT_SUCCESS)))
+ {
+ /* Show the error dialog with details from the exe. */
+ _e_exec_error_dialog(inst->desktop, ecore_exe_cmd_get(ev->exe), ev,
+ ecore_exe_event_data_get(ev->exe, ECORE_EXE_PIPE_ERROR),
+ ecore_exe_event_data_get(ev->exe, ECORE_EXE_PIPE_READ));
+ }
+ instances = evas_hash_find(e_exec_instances, inst->desktop->orig_path);
+ instances = evas_list_remove(instances, inst);
+ evas_hash_direct_add(e_exec_instances, inst->desktop->orig_path, instances);
+ e_exec_start_pending = evas_list_remove(e_exec_start_pending, inst->desktop);
+ if (inst->expire_timer) ecore_timer_del(inst->expire_timer);
+ free(inst);
+ return 1;
+}
+
+static void
+_e_exec_error_dialog(Efreet_Desktop *desktop, const char *exec, Ecore_Exe_Event_Del *event,
+ Ecore_Exe_Event_Data *error, Ecore_Exe_Event_Data *read)
+{
+ E_Config_Dialog *cfd;
+ E_Config_Dialog_View *v;
+ E_Config_Dialog_Data *cfdata;
+ E_Container *con;
+
+ v = E_NEW(E_Config_Dialog_View, 1);
+ if (!v) return;
+ cfdata = E_NEW(E_Config_Dialog_Data, 1);
+ if (!cfdata)
+ {
+ free(v);
+ return;
+ }
+ cfdata->desktop = desktop;
+ if (exec) cfdata->exec = strdup(exec);
+ cfdata->error = error;
+ cfdata->read = read;
+ cfdata->event = *event;
+
+ v->create_cfdata = _create_data;
+ v->free_cfdata = _free_data;
+ v->basic.create_widgets = _basic_create_widgets;
+ v->advanced.create_widgets = _advanced_create_widgets;
+
+ con = e_container_current_get(e_manager_current_get());
+ /* Create The Dialog */
+ cfd = e_config_dialog_new(con, _("Application Execution Error"),
+ "E", "_e_exec_error_exit_dialog",
+ NULL, 0, v, cfdata);
+}
+
+static void
+_fill_data(E_Config_Dialog_Data *cfdata)
+{
+ char buf[4096];
+
+ if (!cfdata->label)
+ {
+ snprintf(buf, sizeof(buf), _("%s stopped running unexpectedly."), cfdata->desktop->name);
+ cfdata->label = strdup(buf);
+ }
+ if ((cfdata->event.exited) && (!cfdata->exit))
+ {
+ snprintf(buf, sizeof(buf),
+ _("An exit code of %i was returned from %s."), cfdata->event.exit_code, cfdata->exec);
+ cfdata->exit = strdup(buf);
+ }
+ if ((cfdata->event.signalled) && (!cfdata->signal))
+ {
+ if (cfdata->event.exit_signal == SIGINT)
+ snprintf(buf, sizeof(buf),
+ _("%s was interrupted by an Interrupt Signal."), cfdata->desktop->exec);
+ else if (cfdata->event.exit_signal == SIGQUIT)
+ snprintf(buf, sizeof(buf), _("%s was interrupted by a Quit Signal."),
+ cfdata->exec);
+ else if (cfdata->event.exit_signal == SIGABRT)
+ snprintf(buf, sizeof(buf),
+ _("%s was interrupted by an Abort Signal."), cfdata->exec);
+ else if (cfdata->event.exit_signal == SIGFPE)
+ snprintf(buf, sizeof(buf),
+ _("%s was interrupted by a Floating Point Error."), cfdata->exec);
+ else if (cfdata->event.exit_signal == SIGKILL)
+ snprintf(buf, sizeof(buf),
+ _("%s was interrupted by an Uninterruptable Kill Signal."), cfdata->exec);
+ else if (cfdata->event.exit_signal == SIGSEGV)
+ snprintf(buf, sizeof(buf),
+ _("%s was interrupted by a Segmentation Fault."), cfdata->exec);
+ else if (cfdata->event.exit_signal == SIGPIPE)
+ snprintf(buf, sizeof(buf),
+ _("%s was interrupted by a Broken Pipe."), cfdata->exec);
+ else if (cfdata->event.exit_signal == SIGTERM)
+ snprintf(buf, sizeof(buf),
+ _("%s was interrupted by a Termination Signal."), cfdata->exec);
+ else if (cfdata->event.exit_signal == SIGBUS)
+ snprintf(buf, sizeof(buf),
+ _("%s was interrupted by a Bus Error."), cfdata->exec);
+ else
+ snprintf(buf, sizeof(buf),
+ _("%s was interrupted by the signal number %i."),
+ cfdata->exec, cfdata->event.exit_signal);
+ cfdata->signal = strdup(buf);
+ /* FIXME: Add sigchld_info stuff
+ * cfdata->event.data
+ * siginfo_t
+ * {
+ * int si_signo; Signal number
+ * int si_errno; An errno value
+ * int si_code; Signal code
+ * pid_t si_pid; Sending process ID
+ * uid_t si_uid; Real user ID of sending process
+ * int si_status; Exit value or signal
+ * clock_t si_utime; User time consumed
+ * clock_t si_stime; System time consumed
+ * sigval_t si_value; Signal value
+ * int si_int; POSIX.1b signal
+ * void * si_ptr; POSIX.1b signal
+ * void * si_addr; Memory location which caused fault
+ * int si_band; Band event
+ * int si_fd; File descriptor
+ * }
+ */
+ }
+}
+
+static void *
+_create_data(E_Config_Dialog *cfd)
+{
+ E_Config_Dialog_Data *cfdata;
+
+ cfdata = cfd->data;
+ _fill_data(cfdata);
+ return cfdata;
+}
+
+static void
+_free_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata)
+{
+ if (cfdata->error) ecore_exe_event_data_free(cfdata->error);
+ if (cfdata->read) ecore_exe_event_data_free(cfdata->read);
+
+ E_FREE(cfdata->exec);
+ E_FREE(cfdata->signal);
+ E_FREE(cfdata->exit);
+ E_FREE(cfdata->label);
+
+ free(cfdata);
+}
+
+static Evas_Object *
+_dialog_scrolltext_create(Evas *evas, char *title, Ecore_Exe_Event_Data_Line *lines)
+{
+ int i;
+ Evas_Object *obj, *os;
+ char *text;
+ char *trunc_note = _("***The remaining output has been truncated. Save the output to view.***\n");
+ int tlen, max_lines;
+
+ os = e_widget_framelist_add(evas, _(title), 0);
+
+ obj = e_widget_textblock_add(evas);
+
+ tlen = 0;
+ for (i = 0; lines[i].line != NULL; i++)
+ {
+ tlen += lines[i].size + 1;
+ /* When the program output is extraordinarily long, it can cause
+ * significant delays during text rendering. Limit to a fixed
+ * number of characters. */
+ if (tlen > MAX_OUTPUT_CHARACTERS)
+ {
+ tlen -= lines[i].size + 1;
+ tlen += strlen(trunc_note);
+ break;
+ }
+ }
+ max_lines = i;
+ text = alloca(tlen + 1);
+
+ if (text)
+ {
+ text[0] = 0;
+ for (i = 0; i < max_lines; i++)
+ {
+ strcat(text, lines[i].line);
+ strcat(text, "\n");
+ }
+
+ /* Append the warning about truncated output. */
+ if (lines[max_lines].line != NULL)
+ strcat(text, trunc_note);
+
+ e_widget_textblock_plain_set(obj, text);
+ }
+ e_widget_min_size_set(obj, 240, 120);
+
+ e_widget_framelist_object_append(os, obj);
+
+ return os;
+}
+
+static Evas_Object *
+_basic_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata)
+{
+ char buf[4096];
+ int error_length = 0;
+ Evas_Object *o, *ob, *os;
+
+ _fill_data(cfdata);
+
+ o = e_widget_list_add(evas, 0, 0);
+
+ ob = e_widget_label_add(evas, cfdata->label);
+ e_widget_list_object_append(o, ob, 1, 1, 0.5);
+
+ if (cfdata->error)
+ error_length = cfdata->error->size;
+ if (error_length)
+ {
+ os = _dialog_scrolltext_create(evas, _("Error Logs"), cfdata->error->lines);
+ e_widget_list_object_append(o, os, 1, 1, 0.5);
+ }
+ else
+ {
+ ob = e_widget_label_add(evas, _("There was no error message."));
+ e_widget_list_object_append(o, ob, 1, 1, 0.5);
+ }
+
+ ob = e_widget_button_add(evas, _("Save This Message"), "enlightenment/run",
+ _dialog_save_cb, NULL, cfdata);
+ e_widget_list_object_append(o, ob, 0, 0, 0.5);
+
+ snprintf(buf, sizeof(buf), _("This error log will be saved as %s/%s.log"),
+ e_user_homedir_get(), cfdata->desktop->name);
+ ob = e_widget_label_add(evas, buf);
+ e_widget_list_object_append(o, ob, 1, 1, 0.5);
+
+ return o;
+}
+
+static Evas_Object *
+_advanced_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata)
+{
+ char buf[4096];
+ int read_length = 0;
+ int error_length = 0;
+ Evas_Object *o, *of, *ob, *ot;
+
+ _fill_data(cfdata);
+
+ o = e_widget_list_add(evas, 0, 0);
+ ot = e_widget_table_add(evas, 0);
+
+ ob = e_widget_label_add(evas, cfdata->label);
+ e_widget_list_object_append(o, ob, 1, 1, 0.5);
+
+ if (cfdata->exit)
+ {
+ of = e_widget_framelist_add(evas, _("Error Information"), 0);
+ ob = e_widget_label_add(evas, _(cfdata->exit));
+ e_widget_framelist_object_append(of, ob);
+ e_widget_list_object_append(o, of, 1, 1, 0.5);
+ }
+
+ if (cfdata->signal)
+ {
+ of = e_widget_framelist_add(evas, _("Error Signal Information"), 0);
+ ob = e_widget_label_add(evas, _(cfdata->signal));
+ e_widget_framelist_object_append(of, ob);
+ e_widget_list_object_append(o, of, 1, 1, 0.5);
+ }
+
+ if (cfdata->read)
+ read_length = cfdata->read->size;
+
+ if (read_length)
+ {
+ of = _dialog_scrolltext_create(evas, _("Output Data"), cfdata->read->lines);
+ /* FIXME: Add stdout "start". */
+ /* FIXME: Add stdout "end". */
+ }
+ else
+ {
+ of = e_widget_framelist_add(evas, _("Output Data"), 0);
+ ob = e_widget_label_add(evas, _("There was no output."));
+ e_widget_framelist_object_append(of, ob);
+ }
+ e_widget_table_object_append(ot, of, 0, 0, 1, 1, 1, 1, 1, 1);
+
+ if (cfdata->error)
+ error_length = cfdata->error->size;
+ if (error_length)
+ {
+ of = _dialog_scrolltext_create(evas, _("Error Logs"), cfdata->error->lines);
+ /* FIXME: Add stderr "start". */
+ /* FIXME: Add stderr "end". */
+ }
+ else
+ {
+ of = e_widget_framelist_add(evas, _("Error Logs"), 0);
+ ob = e_widget_label_add(evas, _("There was no error message."));
+ e_widget_framelist_object_append(of, ob);
+ }
+ e_widget_table_object_append(ot, of, 1, 0, 1, 1, 1, 1, 1, 1);
+
+ e_widget_list_object_append(o, ot, 1, 1, 0.5);
+
+ ob = e_widget_button_add(evas, _("Save This Message"), "enlightenment/run", _dialog_save_cb, NULL, cfdata);
+ e_widget_list_object_append(o, ob, 0, 0, 0.5);
+
+ snprintf(buf, sizeof(buf), _("This error log will be saved as %s/%s.log"),
+ e_user_homedir_get(), cfdata->desktop->name);
+ ob = e_widget_label_add(evas, buf);
+ e_widget_list_object_append(o, ob, 1, 1, 0.5);
+
+ return o;
+}
+
+static void
+_dialog_save_cb(void *data, void *data2)
+{
+ E_Config_Dialog_Data *cfdata;
+ FILE *f;
+ char *text;
+ char buf[1024];
+ char buffer[4096];
+ int read_length = 0;
+ int i, tlen;
+
+ cfdata = data2;
+
+ snprintf(buf, sizeof(buf), "%s/%s.log", e_user_homedir_get(),
+ e_util_filename_escape(cfdata->desktop->name));
+ f = fopen(buf, "w");
+ if (!f) return;
+
+ if (cfdata->exit)
+ {
+ snprintf(buffer, sizeof(buffer), "Error Information:\n\t%s\n\n", cfdata->exit);
+ fwrite(buffer, sizeof(char), strlen(buffer), f);
+ }
+ if (cfdata->signal)
+ {
+ snprintf(buffer, sizeof(buffer), "Error Signal Information:\n\t%s\n\n", cfdata->signal);
+ fwrite(buffer, sizeof(char), strlen(buffer), f);
+ }
+
+ if (cfdata->read)
+ read_length = cfdata->read->size;
+
+ if (read_length)
+ {
+ tlen = 0;
+ for (i = 0; cfdata->read->lines[i].line != NULL; i++)
+ tlen += cfdata->read->lines[i].size + 2;
+ text = alloca(tlen + 1);
+ if (text)
+ {
+ text[0] = 0;
+ for (i = 0; cfdata->read->lines[i].line != NULL; i++)
+ {
+ strcat(text, "\t");
+ strcat(text, cfdata->read->lines[i].line);
+ strcat(text, "\n");
+ }
+ snprintf(buffer, sizeof(buffer), "Output Data:\n%s\n\n", text);
+ fwrite(buffer, sizeof(char), strlen(buffer), f);
+ }
+ }
+ else
+ {
+ snprintf(buffer, sizeof(buffer), "Output Data:\n\tThere was no output\n\n");
+ fwrite(buffer, sizeof(char), strlen(buffer), f);
+ }
+
+ /* Reusing this var */
+ read_length = 0;
+ if (cfdata->error)
+ read_length = cfdata->error->size;
+
+ if (read_length)
+ {
+ tlen = 0;
+ for (i = 0; cfdata->error->lines[i].line != NULL; i++)
+ tlen += cfdata->error->lines[i].size + 1;
+ text = alloca(tlen + 1);
+ if (text)
+ {
+ text[0] = 0;
+ for (i = 0; cfdata->error->lines[i].line != NULL; i++)
+ {
+ strcat(text, "\t");
+ strcat(text, cfdata->error->lines[i].line);
+ strcat(text, "\n");
+ }
+ snprintf(buffer, sizeof(buffer), "Error Logs:\n%s\n", text);
+ fwrite(buffer, sizeof(char), strlen(buffer), f);
+ }
+ }
+ else
+ {
+ snprintf(buffer, sizeof(buffer), "Error Logs:\n\tThere was no error message\n");
+ fwrite(buffer, sizeof(char), strlen(buffer), f);
+ }
+
+ fclose(f);
+}
diff --git a/src/bin/e_exec.h b/src/bin/e_exec.h
index ab18f8522..75062c4de 100644
--- a/src/bin/e_exec.h
+++ b/src/bin/e_exec.h
@@ -7,5 +7,9 @@
#ifndef E_EXEC_H
#define E_EXEC_H
+EAPI int e_exec_init(void);
+EAPI int e_exec_shutdown(void);
+EAPI int e_exec(E_Zone *zone, Efreet_Desktop *desktop, const char *exec, Ecore_List *files, const char *launch_method);
+
#endif
#endif
diff --git a/src/bin/e_main.c b/src/bin/e_main.c
index dac5c6fe6..5bd620d77 100644
--- a/src/bin/e_main.c
+++ b/src/bin/e_main.c
@@ -681,6 +681,14 @@ main(int argc, char **argv)
_e_main_shutdown(-1);
}
_e_main_shutdown_push(e_app_shutdown);
+ TS("exec");
+ /* init app system */
+ if (!e_exec_init())
+ {
+ e_error_message_show(_("Enlightenment cannot set up its exec system."));
+ _e_main_shutdown(-1);
+ }
+ _e_main_shutdown_push(e_exec_shutdown);
TS("remember");
/* do remember stuff */
if (!e_remember_init(after_restart ? E_STARTUP_RESTART: E_STARTUP_START))