forked from Sep102/swo-tracer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtracer-linux.c
122 lines (99 loc) · 2.53 KB
/
tracer-linux.c
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
/* swo-tracer: listen for and parse ARM SWO trace output
*
* Copyright (c) 2013 Andrey Yurovsky
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the author. The name of the
* author may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#include <stdio.h>
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/inotify.h>
#include "frame.h"
const char *usage_str = "usage: %s [-t] <trace_path>\n";
int running = 1;
static void handle_signal(int sig)
{
if (sig == SIGINT)
running = 0;
}
static void process_events(int fd, int fd_d)
{
struct inotify_event ev;
if (read(fd, &ev, sizeof(ev)) > 0) {
if (ev.mask & IN_MODIFY)
read_frame(fd_d);
}
}
static int check_event(int fd)
{
fd_set rfds;
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
return select(FD_SETSIZE, &rfds, NULL, NULL, NULL);
}
int main(int argc, char **argv)
{
int opt;
int fd;
int fd_d;
int ret = 0;
int flags = O_RDONLY;
setvbuf(stdout, NULL, _IONBF, 0);
while ((opt = getopt(argc, argv, "t")) != -1) {
switch (opt) {
case 't':
flags = (O_RDWR | O_TRUNC);
break;
default:
fprintf(stderr, usage_str, argv[0]);
exit(EXIT_FAILURE);
}
}
if (optind >= argc) {
fprintf(stderr, usage_str, argv[0]);
exit(EXIT_FAILURE);
}
fd_d = open(argv[optind], flags);
if (!(flags & O_TRUNC))
while (read_frame(fd_d) > 0);
fd = inotify_init();
if (fd >= 0 && fd_d >= 0) {
int wd;
struct sigaction sa;
sa.sa_handler = handle_signal;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sigaction(SIGINT, &sa, NULL);
wd = inotify_add_watch(fd, argv[optind], IN_MODIFY);
while (running) {
if (check_event(fd) > 0)
process_events(fd, fd_d);
else
break;
}
fprintf(stderr, " Exiting..\n");
close(fd_d);
inotify_rm_watch(fd, wd);
} else {
fprintf(stderr, "unable to open \"%s\" for reading\n", argv[optind]);
ret = EXIT_FAILURE;
}
return ret;
}