summaryrefslogtreecommitdiffstats
path: root/src/Daemon
diff options
context:
space:
mode:
Diffstat (limited to 'src/Daemon')
-rw-r--r--src/Daemon/CrashWatcher.cpp176
-rw-r--r--src/Daemon/CrashWatcher.h58
-rw-r--r--src/Daemon/Daemon.cpp66
-rw-r--r--src/Daemon/Makefile.am6
4 files changed, 306 insertions, 0 deletions
diff --git a/src/Daemon/CrashWatcher.cpp b/src/Daemon/CrashWatcher.cpp
new file mode 100644
index 00000000..2155b2b7
--- /dev/null
+++ b/src/Daemon/CrashWatcher.cpp
@@ -0,0 +1,176 @@
+/*
+ Copyright (C) 2009 Jiri Moskovcak (jmoskovc@redhat.com)
+ Copyright (C) 2009 RedHat inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY 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, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "CrashWatcher.h"
+#include <unistd.h>
+#include <iostream>
+#include <climits>
+#include <cstdlib>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <cstring>
+#include <csignal>
+
+void terminate(int signal)
+{
+ exit(0);
+}
+
+gboolean CCrashWatcher::handle_event_cb(GIOChannel *gio, GIOCondition condition, gpointer daemon){
+ GIOError err;
+ char buf[INOTIFY_BUFF_SIZE];
+ guint len;
+ int i = 0;
+ err = g_io_channel_read (gio, buf, INOTIFY_BUFF_SIZE, &len);
+ if (err != G_IO_ERROR_NONE) {
+ g_warning ("Error reading inotify fd: %d\n", err);
+ return FALSE;
+ }
+ /* reconstruct each event and send to the user's callback */
+ while (i < len) {
+ const char *name;
+ struct inotify_event *event;
+
+ event = (struct inotify_event *) &buf[i];
+ if (event->len)
+ name = &buf[i] + sizeof (struct inotify_event);
+ i += sizeof (struct inotify_event) + event->len;
+#ifdef DEBUG
+ std::cout << "Created file: " << name << std::endl;
+#endif /*DEBUG*/
+ /* send message to dbus */
+ CCrashWatcher *cc = (CCrashWatcher*)daemon;
+ cc->m_nDbus_manager.SendMessage("Crash", name);
+ }
+ return TRUE;
+}
+
+CCrashWatcher::CCrashWatcher(const std::string& pPath)
+{
+ int watch = 0;
+ m_sTarget = pPath;
+ m_nMainloop = g_main_loop_new(NULL,FALSE);
+ /* register on dbus */
+ m_nDbus_manager.RegisterService();
+ if((m_nFd = inotify_init()) == -1){
+ throw std::string("Init Failed");
+ //std::cerr << "Init Failed" << std::endl;
+ exit(-1);
+ }
+ if((watch = inotify_add_watch(m_nFd, pPath.c_str(), IN_CREATE)) == -1){
+ throw std::string("Add watch failed");
+ //std::cerr << "Add watch failed: " << pPath << std::endl;
+ exit(-1);
+ }
+ m_nGio = g_io_channel_unix_new(m_nFd);
+}
+
+CCrashWatcher::~CCrashWatcher()
+{
+}
+
+void CCrashWatcher::Lock()
+{
+ int lfp = open("crashcatcher.lock",O_RDWR|O_CREAT,0640);
+ if (lfp < 0)
+ throw "CCrashWatcher.cpp:can not open lock file";
+ if (lockf(lfp,F_TLOCK,0) < 0)
+ throw "CCrashWatcher.cpp:Lock:cannot create lock on lockfile";
+ /* only first instance continues */
+ //sprintf(str,"%d\n",getpid());
+ //write(lfp,str,strlen(str)); /* record pid to lockfile */
+}
+
+void CCrashWatcher::StartWatch()
+{
+ char *buff = new char[INOTIFY_BUFF_SIZE];
+ int len = 0;
+ int i = 0;
+ char action[FILENAME_MAX];
+ struct inotify_event *pevent;
+ //run forever
+ while(1){
+ i = 0;
+ len = read(m_nFd,buff,INOTIFY_BUFF_SIZE);
+ while(i < len){
+ pevent = (struct inotify_event *)&buff[i];
+ if (pevent->len)
+ std::strcpy(action, pevent->name);
+ else
+ std::strcpy(action, m_sTarget.c_str());
+ i += sizeof(struct inotify_event) + pevent->len;
+#ifdef DEBUG
+ std::cout << "Created file: " << action << std::endl;
+#endif /*DEBUG*/
+ }
+ }
+ delete[] buff;
+}
+
+/* daemon loop with glib */
+void CCrashWatcher::GStartWatch()
+{
+ char *buff = new char[INOTIFY_BUFF_SIZE];
+ int len = 0;
+ int i = 0;
+ char action[FILENAME_MAX];
+ struct inotify_event *pevent;
+ g_io_add_watch (m_nGio, G_IO_IN, handle_event_cb, this);
+ //enter the event loop
+ g_main_run (m_nMainloop);
+ delete[] buff;
+}
+
+void CCrashWatcher::RegisterSignals()
+{
+ signal(SIGTERM, terminate);
+}
+
+void CCrashWatcher::Daemonize()
+{
+#ifdef DEBUG
+ std::cout << "Daemonize" << std::endl;
+#endif
+ // forking to background
+ pid_t pid = fork();
+ if (pid < 0)
+ {
+ throw "CCrashWatcher.cpp:Daemonize:Fork error";
+ }
+ /* parent exits */
+ if (pid > 0) _exit(0);
+ /* child (daemon) continues */
+ pid_t sid = setsid();
+ if(sid == -1){
+ throw "CCrashWatcher.cpp:Daemonize:setsid failed";
+ }
+ Lock();
+ GStartWatch();
+}
+
+void CCrashWatcher::Run()
+{
+#ifdef DEBUG
+ std::cout << "Run" << std::endl;
+#endif
+ Lock();
+ GStartWatch();
+}
+
diff --git a/src/Daemon/CrashWatcher.h b/src/Daemon/CrashWatcher.h
new file mode 100644
index 00000000..77cc1562
--- /dev/null
+++ b/src/Daemon/CrashWatcher.h
@@ -0,0 +1,58 @@
+/*
+ Copyright (C) 2009 Jiri Moskovcak (jmoskovc@redhat.com)
+ Copyright (C) 2009 RedHat inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY 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, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef CRASHWATCHER_H_
+#define CRASHWATCHER_H_
+
+#include <string>
+#include <sys/inotify.h>
+#include <sys/inotify.h>
+#include <glib.h>
+#include "DBusManager.h"
+#include "MiddleWare.h"
+
+// 1024 simultaneous actions
+#define INOTIFY_BUFF_SIZE ((sizeof(struct inotify_event)+FILENAME_MAX)*1024)
+
+
+class CCrashWatcher
+{
+ private:
+ static gboolean handle_event_cb(GIOChannel *gio, GIOCondition condition, gpointer data);
+ void RegisterSignals();
+ void StartWatch();
+ void GStartWatch();
+ void Lock();
+
+ CDBusManager m_nDbus_manager;
+ int m_nFd;
+ GIOChannel* m_nGio;
+ GMainLoop *m_nMainloop;
+ std::string m_sTarget;
+ public:
+ CCrashWatcher(const std::string& pPath);
+ //CCrashWatcher();
+ ~CCrashWatcher();
+ //run as daemon
+ void Daemonize();
+ //don't go background - for debug
+ void Run();
+};
+
+#endif /*CRASHWATCHER_H_*/
diff --git a/src/Daemon/Daemon.cpp b/src/Daemon/Daemon.cpp
new file mode 100644
index 00000000..2f0e575b
--- /dev/null
+++ b/src/Daemon/Daemon.cpp
@@ -0,0 +1,66 @@
+/*
+ Copyright (C) 2009 Jiri Moskovcak (jmoskovc@redhat.com)
+ Copyright (C) 2009 RedHat inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY 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, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "CrashWatcher.h"
+#include <iostream>
+
+#define daemonize 0
+
+int main(int argc, char** argv){
+ try{
+ CCrashWatcher daemon(DEBUG_DUMPS_DIR);
+ //if (argc > 1){
+ // if (strcmp(argv[1], "-d") == 0){
+ // daemonize = 0;
+ // }
+ // }
+ if(daemonize){
+ try{
+ daemon.Daemonize();
+ }
+ catch(std::string err)
+ {
+ std::cerr << err << std::endl;
+ }
+ catch(...){
+ std::cerr << "daemon.cpp:Daemonize" << std::endl;
+ }
+ }
+ else{
+ try{
+ #ifdef DEBUG
+ std::cerr << "trying to run" << std::endl;
+ #endif /*DEBUG*/
+ daemon.Run();
+ }
+ catch(std::string err)
+ {
+ std::cerr << err << std::endl;
+ }
+ catch(...){
+ std::cerr << "daemon.cpp:Run" << std::endl;
+ }
+ }
+ }
+ catch(std::string err)
+ {
+ std::cerr << "Cannot create daemon: " << err << std::endl;
+ }
+}
+
diff --git a/src/Daemon/Makefile.am b/src/Daemon/Makefile.am
new file mode 100644
index 00000000..395eb120
--- /dev/null
+++ b/src/Daemon/Makefile.am
@@ -0,0 +1,6 @@
+bin_PROGRAMS = CrashCatcher
+CrashCatcher_SOURCES = CrashWatcher.cpp CrashWatcher.h Daemon.cpp
+CrashCatcher_CPPFLAGS = -I../../lib/MiddleWare \
+ -I../../lib/DBus \
+ -DDEBUG_DUMPS_DIR=\"$(DEBUG_DUMPS_DIR)\" $(DBUS_GLIB_CFLAGS)
+CrashCatcher_LDADD = ../../lib/MiddleWare/libMiddleWare.la ../../lib/DBus/libDBus.la $(DL_LIBS)