Startup make some noise :)

Crash dialog will cleanup generated data. Also will
check availability to write/read data it generates.
This commit is contained in:
Sanel Zukan 2007-09-03 12:24:01 +00:00
parent 8c57ce3e43
commit df0031d9dd
10 changed files with 78 additions and 236 deletions

View File

@ -13,11 +13,13 @@
#include "icons/core.xpm"
#include "Crash.h"
#include "Spawn.h"
#include <FL/Fl.h>
#include <FL/Fl_Pixmap.h>
#include <edelib/Nls.h>
#include <stdio.h> // snprintf
#include <edelib/Nls.h>
#include <edelib/File.h>
#include <edelib/Directory.h>
#define DIALOG_W 380
#define DIALOG_H 130
@ -90,8 +92,50 @@ void CrashDialog::show_details(void) {
if(!trace_loaded) {
trace_buff->remove(0, trace_buff->length());
spawn_backtrace(cmd.c_str(), "core", "/tmp/gdb_output", "/tmp/gdb_script");
trace_buff->appendfile("/tmp/gdb_output");
edelib::String gdb_path = edelib::file_path("gdb");
if(gdb_path.empty()) {
trace_buff->append(_("Unable to load gdb. Is it installed ?"));
trace_loaded = 0;
return;
}
// check if we can write in /tmp; if not, try with $HOME
edelib::String dir = "/tmp";
if(!edelib::dir_writeable(dir.c_str())) {
dir = edelib::dir_home();
if(!edelib::dir_writeable(dir.c_str())) {
trace_buff->append(_("Don't have permissions to write either to /tmp or $HOME"));
trace_loaded = 0;
return;
}
}
edelib::String gdb_output, gdb_script;
gdb_output = gdb_script = dir;
gdb_output += "/.gdb_output";
gdb_script += "/.gdb_script";
const char* core_file = "core";
if(spawn_backtrace(gdb_path.c_str(), cmd.c_str(), core_file, gdb_output.c_str(), gdb_script.c_str()) == -1) {
trace_buff->append(_("Unable to properly execute gdb"));
trace_loaded = 0;
return;
}
if(!edelib::file_exists(gdb_output.c_str())) {
trace_buff->append(_("Strange, can't find gdb output that I was just wrote to"));
trace_loaded = 0;
return;
}
trace_buff->appendfile(gdb_output.c_str());
edelib::file_remove(gdb_output.c_str());
edelib::file_remove(gdb_script.c_str());
edelib::file_remove(core_file);
trace_loaded = 1;
}
}

View File

@ -126,7 +126,7 @@ int get_string_property_value(Atom at, char* txt, int txt_len) {
}
strncpy(txt, vnames[0], txt_len);
txt[txt_len] = '\0';
txt[txt_len] = 0;
XFreeStringList(vnames);
return 1;
}
@ -224,6 +224,11 @@ bool EvokeService::init_splash(const char* config, bool no_splash, bool dry_run)
if(c.get("evoke", "Splash", buff, sizeof(buff)))
splashimg = buff;
edelib::String sound;
if(c.get("evoke", "Sound", buff, sizeof(buff)))
sound = buff;
// Startup key must exists
if(!c.get("evoke", "Startup", buff, sizeof(buff)))
return false;
@ -269,6 +274,7 @@ bool EvokeService::init_splash(const char* config, bool no_splash, bool dry_run)
Splash sp(no_splash, dry_run);
sp.set_clients(&clients);
sp.set_background(&splashimg);
sp.set_sound(&sound);
sp.run();
@ -494,6 +500,7 @@ void EvokeService::run_program(const char* cmd, bool enable_vars) {
register_process(scmd.c_str(), child);
}
#if 0
void EvokeService::heuristic_run_program(const char* cmd) {
if(strncmp(cmd, "$TERM ", 6) == 0) {
run_program(cmd);
@ -554,6 +561,7 @@ void EvokeService::heuristic_run_program(const char* cmd) {
run_program(fcmd.c_str());
}
#endif
void EvokeService::register_process(const char* cmd, pid_t pid) {
EvokeProcess pc;

View File

@ -80,7 +80,7 @@ class EvokeService {
void service_watcher(int pid, int signum);
void run_program(const char* cmd, bool enable_vars = 1);
void heuristic_run_program(const char* cmd);
//void heuristic_run_program(const char* cmd);
void register_process(const char* cmd, pid_t pid);
void unregister_process(pid_t pid);
bool find_and_unregister_process(pid_t pid, EvokeProcess& pc);

View File

@ -12,6 +12,8 @@ SubDir TOP evoke ;
SOURCE = evoke.cpp EvokeService.cpp Spawn.cpp Splash.cpp Log.cpp Logout.cpp Crash.cpp Autostart.cpp ;
LinkAgainst evoke : -lao -lvorbis -lvorbisfile -lmad ;
EdeProgram evoke : $(SOURCE) ;
FltkProgramBare test/evoke_test : test/evoke_test.cpp ;
#TranslationStrings locale : $(SOURCE) ;

View File

@ -138,7 +138,7 @@ int spawn_program_with_core(const char* cmd, SignalWatch* wf, pid_t* child_pid_r
return ret;
}
int spawn_backtrace(const char* program, const char* core, const char* output, const char* script) {
int spawn_backtrace(const char* gdb_path, const char* program, const char* core, const char* output, const char* script) {
const char* gdb_script = "bt\nquit\n";
const int gdb_script_len = 8;
@ -164,7 +164,7 @@ int spawn_backtrace(const char* program, const char* core, const char* output, c
close(ofd);
char* argv[8];
argv[0] = "gdb";
argv[0] = (char*)gdb_path;
argv[1] = "--quiet";
argv[2] = "--batch";
argv[3] = "-x";
@ -184,178 +184,3 @@ int spawn_backtrace(const char* program, const char* core, const char* output, c
return 0;
}
#if 0
int spawn_backtrace(int crash_pid, const char* output, const char* script) {
const char* gdb_script = "info threads\nthread apply all bt full\nquit\n";
const int gdb_script_len = 43;
//const char* gdb_script = "bt\nquit\n";
//const int gdb_script_len = 8;
pid_t parent_pid, child_pid;
//kill(crash_pid, SIGCONT);
char parent_pid_str[64];
parent_pid = crash_pid;
kill(parent_pid, SIGCONT);
//parent_pid = getpid();
sprintf(parent_pid_str, "%ld", (long)parent_pid);
// file with gdb commands
int sfd = open(script, O_WRONLY | O_TRUNC | O_CREAT, 0770);
if(sfd == -1)
return -1;
write(sfd, gdb_script, gdb_script_len);
close(sfd);
// output file with gdb backtrace
int ofd = open(output, O_WRONLY | O_TRUNC | O_CREAT, 0770);
if(ofd == -1)
return -1;
child_pid = fork();
if(child_pid == -1)
return -1;
else if(child_pid == 0) {
//dup2(ofd, 1);
close(ofd);
char* argv[8];
argv[0] = "gdb";
argv[1] = "--quiet";
argv[2] = "--batch";
argv[3] = "-x";
argv[4] = (char*)script;
argv[5] = "--pid";
argv[6] = parent_pid_str;
argv[7] = 0;
//argv[5] = "--pid";
//argv[6] = parent_pid_str;
//argv[7] = 0;
printf("%s %s %s %s %s %s %s\n", argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6]);
execvp(argv[0], argv);
return -1;
} else {
/*
int status;
waitpid(child_pid, &status, 0);
*/
}
//unlink(script);
return 0;
}
#if 0
int spawn_backtrace(const char* output, const char* script){
pid_t pid, parent_pid;
int ifd[2], ofd[2], efd[2];
const char* gdb_script = "info threads\nthread apply all by\nquit\n";
const int gdb_script_len = 38;
puts("xxxx");
// write script for gdb
int fds = open(script, O_WRONLY | O_CREAT | O_TRUNC, 0770);
if(fds == -1)
return -1;
write(fds, gdb_script, gdb_script_len);
close(fds);
puts("yyyyy");
errno = 0;
// open output for gdb trace
int fdo = open(output, O_WRONLY, O_CREAT | O_TRUNC, 0770);
if(fdo == -1) {
printf("can't open fdo(%s): %s\n", output, strerror(errno));
return -1;
}
parent_pid = getppid();
char parent_pid_str[64];
sprintf(parent_pid_str, "%d", parent_pid);
char* argv[8];
argv[0] = "gdb";
argv[1] = "--quiet";
argv[2] = "--batch";
argv[3] = "-x";
argv[4] = (char*)script;
argv[5] = "--pid";
argv[6] = parent_pid_str;
argv[7] = 0;
puts("ayyyy");
if(pipe(ifd) == -1) {
printf("cant open ifd pipe: %s\n", strerror(errno));
}
if(pipe(ofd) == -1) {
printf("cant open ofd pipe: %s\n", strerror(errno));
}
if(pipe(efd) == -1) {
printf("cant open efd pipe: %s\n", strerror(errno));
}
pid = fork();
if(pid == -1) {
close(ifd[0]); close(ifd[1]);
close(ofd[0]); close(ofd[1]);
close(efd[0]); close(efd[1]);
return -1;
} else if(pid == 0) {
// child
printf("gdb pid is %i\n", getpid());
printf("%s %s %s %s %s %s %s\n", argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6]);
close(ifd[1]);
fclose(stdin);
dup(ifd[0]);
close(ofd[0]);
fclose(stdout);
dup(ofd[1]);
close(efd[0]);
fclose(stderr);
dup(efd[1]);
execvp(argv[0], (char**)argv);
return -1;
} else {
// parent
fclose(stdin);
close(ifd[0]);
close(ofd[1]);
close(efd[1]);
write(fdo, "The trace:\n", 11);
close(ifd[1]);
close(ofd[0]);
close(efd[0]);
close(fdo);
kill(pid, SIGKILL);
waitpid(pid, NULL, 0);
//_exit(0);
}
return 0;
}
#endif
#endif

View File

@ -35,6 +35,6 @@ typedef void (SignalWatch)(int pid, int status);
int spawn_program(const char* cmd, SignalWatch* wf = 0, pid_t* child_pid_ret = 0, const char* ofile = 0);
int spawn_program_with_core(const char* cmd, SignalWatch* wf = 0, pid_t* child_pid_ret = 0);
int spawn_backtrace(const char* program, const char* core, const char* output, const char* script);
int spawn_backtrace(const char* gdb_path, const char* program, const char* core, const char* output, const char* script);
#endif

View File

@ -16,6 +16,7 @@
#include <edelib/Run.h>
#include <edelib/Debug.h>
#include <edelib/Nls.h>
#include <edelib/Sound.h>
#include <FL/Fl_Shared_Image.h>
#include <FL/Fl.h>
@ -170,6 +171,9 @@ void Splash::run(void) {
int sh = DisplayHeight(fl_display, fl_screen);
position(sw/2 - w()/2, sh/2 - h()/2);
if(sound && !sound->empty())
edelib::SoundSystem::init();
show();
Fl::add_timeout(TIMEOUT_START, runner_cb, this);
@ -185,10 +189,16 @@ void Splash::run(void) {
// make sure MappingNotify keeps this window at the top
EvokeService::instance()->register_top(this);
if(edelib::SoundSystem::inited())
edelib::SoundSystem::play(sound->c_str(), 0);
while(shown())
Fl::wait();
EvokeService::instance()->unregister_top();
if(edelib::SoundSystem::inited())
edelib::SoundSystem::shutdown();
}
// called when splash option is on
@ -204,6 +214,7 @@ bool Splash::next_client(void) {
return false;
}
EASSERT(counter < clist->size() && "Internal error; 'counter' out of bounds");
char buff[1024];
@ -221,32 +232,6 @@ bool Splash::next_client(void) {
++clist_it;
++counter;
return true;
#if 0
/*
* This was vector implementation; I'm leaving here
* untill list is proven to be safe. If code is changed
* back to vector, make sure to update rest code removing
* iterators.
*/
if(counter >= clist->size()) {
counter = 0;
return false;
}
char buff[1024];
const char* msg = (*clist)[counter].message.c_str();
const char* cmd = (*clist)[counter].exec.c_str();
snprintf(buff, sizeof(buff), _("Starting %s..."), msg);
icons[counter]->show();
msgbox->copy_label(buff);
redraw();
if(!dry_run)
spawn_program(cmd);
counter++;
#endif
}
// called when splash option is off
@ -277,29 +262,4 @@ bool Splash::next_client_nosplash(void) {
++clist_it;
++counter;
return true;
#if 0
/*
* This was vector implementation; I'm leaving here
* untill list is proven to be safe. If code is changed
* back to vector, make sure to update rest code removing
* iterators.
*/
if(counter >= clist->size()) {
counter = 0;
return false;
}
char buff[1024];
const char* msg = (*clist)[counter].message.c_str();
const char* cmd = (*clist)[counter].exec.c_str();
snprintf(buff, sizeof(buff), _("Starting %s..."), msg);
printf("%s\n", buff);
if(!dry_run)
spawn_program(cmd);
counter++;
#endif
}

View File

@ -22,6 +22,7 @@ class Splash : public Fl_Double_Window {
private:
ClientList* clist;
const edelib::String* bkg;
const edelib::String* sound;
unsigned int counter;
bool no_splash;
bool dry_run;
@ -41,6 +42,7 @@ class Splash : public Fl_Double_Window {
*/
void set_clients(ClientList* cl) { clist = cl; }
void set_background(const edelib::String* s) { bkg = s; }
void set_sound(const edelib::String* s) { sound = s; }
const ClientList* get_clients(void) const { return clist; }
bool next_client(void);

View File

@ -4,7 +4,8 @@
Startup = edewm,eiconman,eworkpanel,xscreensaver
ImagesDirectory = images
#ImagesDirectory = /home/sanel/blentavo/EDE/ede2/evoke/images
Splash = splash-alpha1.png
Splash = splash-alpha1.png
Sound = startup.ogg
[edewm]
Icon = edewm.png

BIN
evoke/startup.ogg Normal file

Binary file not shown.