summaryrefslogtreecommitdiffstats
path: root/Master/Embedded Frameworks/Prakt5/watchdog/hwwatchdog.cpp
blob: 626f20ce08601d02d1bb55c05b6bf38b916ba5ba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// File: hwwatchdog.cpp
// Purpose: Simulate a HW-Watchdog, which kills given processes after a given interval,
//			if it was not triggered on a named semaphore. see usage text.
// Authors: Pierre Schnarz, Sven Eisenhauer
// 14.06.2010 Initial coding
//
// Note: Named Semaphore code is POSIX. Tested on Linux only, show work on QNX.
//		 Perhaps check header files on QNX
//	Important: in killProcs change cmd to list processes!
//
#ifdef LINUX

#include <semaphore.h>
#include <time.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>

// ugly global variables. needed in sig_handler
char* semName;
sem_t* semPtr;

void usage(const char* progname)
{
	printf("Usage: %s <timeout> <semaphore_name> <proc_name>\n",progname);
	printf("\ttimeout:\tseconds to wait until watchdog time out\n");
	printf("\tsemaphore_name:\tname of the semaphore to trigger watchdog\n");	
	printf("\t\t\tfull path will become /dev/shm/sem.<semaphore_name>\n");
	printf("\tproc_name: fname (executable name) of processes to kill\n");	
	printf("Exit with Crtl-C\n");	
}

void sigint_handler(int sig) {
  printf("exiting\n");
  sem_close(semPtr);
  sem_unlink(semName);
  exit(EXIT_SUCCESS);	
}

void killProcs(char* procName)
{
	FILE* fp;
	const int BUFF_SIZE = 4096;
	//TODO: make cmd portable to QNX (pidin something...)	
	const char* cmd = "ps -eo pid,fname";
	char buffer[BUFF_SIZE];
	fp = popen(cmd,"r");
	int pid = -1;
	int byte_count = 0;
	char res;
	int kill_res = -1;
	while (((res = fgetc(fp)) != EOF) && (byte_count < BUFF_SIZE) )
	{
		buffer[byte_count++] = res;
	}
	char* line = strtok(buffer,"\n");
	//int line_count = 0;
	while( (line=strtok(NULL,"\n")) != NULL ) {
		char fname[8];
		sscanf(line,"%d %s",&pid,fname);
		//printf("line %d: [%s] pid: %d fname: [%s]\n",++line_count,line,pid,fname);
		if(strncmp(procName,fname,8) == 0) {
			printf("killing process %s pid:%d\n",fname,pid);
			kill_res = kill(pid,SIGTERM);
			if(kill_res != 0) {
				printf("Error killing %d : %d\n",pid,errno);
			} else {
				printf("Killed %d\n",pid);
			}
		}
	}
	pclose(fp);
}

int main(int argc, char** argv)
{
  struct timespec ts;
  mode_t semMode = S_IRWXU|S_IRWXG|S_IRWXO;
  int s;
  long timeOut;
  const char* progName = argv[0];
  char* proc;
  
  if(argc != 4) {
  	usage(progName);
  	exit(EXIT_FAILURE);
  }
  
  timeOut = strtol(argv[1],NULL,10);
  semName = argv[2];
  proc = argv[3];
  if (clock_gettime(CLOCK_REALTIME, &ts) == -1) {
        printf("clock_gettime failed\n");
	exit(EXIT_FAILURE);
  }
  
  // set signal handler for cleanup
  (void) signal(SIGINT,sigint_handler);

  
  ts.tv_sec += timeOut; // wait timeOut seconds
  semPtr = sem_open(semName,O_CREAT,semMode,0);
  if(SEM_FAILED == semPtr) {
    printf("Could not create named semaphore\n");
    return -1;
  }
  do
  {
  	// wait until time specified in ts on semaphore
    s = sem_timedwait(semPtr, &ts);
    /* Check what happened */
    if (s == -1) {
	  if (errno == ETIMEDOUT) {
	      printf("sem_timedwait() timed out\n");
	      printf("kill Proccesses\n");
	      killProcs(proc);
	  }
	  else {
	      printf("sem_timedwait some other error: %d\n",errno);
	      exit(EXIT_FAILURE);
	  }
    } else {
	  printf("sem_timedwait() succeeded. Watchdog triggered\n");
    }
    if (clock_gettime(CLOCK_REALTIME, &ts) == -1) {
	  printf("clock_gettime failed\n");
	  return -1;
    }
    ts.tv_sec += timeOut; // wait timeOut seconds
    printf("next loop hw watchdog\n");
  } while (true);
  exit(EXIT_SUCCESS);
}

#endif // LINUX