-
Notifications
You must be signed in to change notification settings - Fork 27
/
tstamp.c
148 lines (125 loc) · 2.94 KB
/
tstamp.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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/*
* Purpose of this utility is to timestamp each line coming over stdin
* USAGES:
* tstamp.exe < /dev/ttyS0
* <commands> | tstamp.exe
*
* Kent:
* 1. /usr/sbin/venc --chain -p /var/run/venc.pid 2>&1 | /home/kent/practice/tstamp.dm365.out
* 2. find /usr 2>&1 | /home/kent/practice/tstamp.dm365.out
*
* Note: sometimes you have to set stand stream unbuffered to take effect. e.g., configer.II
* setvbuf(stdout, 0, 2, 0);
* setvbuf(stderr, 0, 2, 0);
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <time.h>
#include <sys/time.h>
#include <sys/signal.h>
#define MAX_BUF_SIZE (10*1024)
//Kent, add for read()
#include <string.h>
#include <unistd.h>
#define STDIN_FD (0)
char buf[MAX_BUF_SIZE];
// Global variables that control process shutdown.
sig_atomic_t graceful_quit = 0;
// Signal handler for SIGINT.
void SIGINT_handler (int signum)
{
assert (signum == SIGINT);
graceful_quit = 1;
}
// Signal handler for SIGQUIT.
void SIGQUIT_handler (int signum)
{
assert (signum == SIGQUIT);
graceful_quit = 1;
}
int main(int argc, const char *argv[])
{
struct timeval tv;
double time_start,time_now,time_prev;
int first = 1;
int bNewlineTerminated = 0;
struct sigaction sa;
//Kent
int read_ret = 0;
char *fgets_ret = NULL;
char crln = '\n';
sigemptyset (&sa.sa_mask);
sa.sa_flags = 0;
// as of now no arguments are allowed. print usage
if (argc != 1)
{
if (0 == strncmp("-n", argv[1], 2))
{
printf("[info] Use newline terminated\n");
bNewlineTerminated = 1;
crln = ' ';
}
else
{
printf(
"Timestamps each line coming over stdin\n"
"\tUSAGES:\n"
"\t\t-n : use newline terminated mode\n"
"\tEXAMPLES:\n"
"\t\ttstamp.exe < /dev/ttyS0\n"
"\t\t<commands> | tstamp.exe\n"
"\n"
);
exit(0);
}
}
// Register the handler for SIGINT.
sa.sa_handler = SIGINT_handler;
sigaction (SIGINT, &sa, 0);
// Register the handler for SIGQUIT.
sa.sa_handler = SIGQUIT_handler;
sigaction (SIGQUIT, &sa, 0);
printf(
"\tcolumn1 is elapsed time since first message\n"
"\tcolumn2 is elapsed time since previous message\n"
"\tcolumn3 is the message\n"
);
while (graceful_quit == 0)
{
if(bNewlineTerminated)
{
// NOTE: fgets() is enabled by default, thus it stop only when newline terminated.
fgets_ret = fgets(buf, MAX_BUF_SIZE, stdin);
}
else
{
read_ret = read(STDIN_FD, buf, MAX_BUF_SIZE);
}
if((fgets_ret != NULL) || (read_ret != 0))
{
// get system time
gettimeofday(&tv, NULL);
// convert to double
time_now = tv.tv_sec + (tv.tv_usec*(1.0/1000000.0));
// if first time, notedown the time_start
if (first)
{
first = 0, time_start = time_prev = time_now;
}
fprintf(stderr
,"%c%08li.%06li %03.3f %02.3f: %s"
,crln
,(tv.tv_sec)
,(long)(tv.tv_usec)
,(float)(time_now-time_start)
,(float)(time_now-time_prev)
,buf
);
time_prev = time_now;
}
}
fflush(NULL);
exit(0);
}