forked from kaiwan/L1_sysprg_trg
-
Notifications
You must be signed in to change notification settings - Fork 0
/
common.c
230 lines (201 loc) · 5.08 KB
/
common.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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
/*
* common.c
* Brief Description:
* This is the 'common' code that gets dynamically linked into
* all binary executables.
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include "common.h"
int handle_err(int fatal, const char *fmt, ...)
{
#define ERRSTRMAX 512
char *err_str;
va_list argp;
err_str = malloc(ERRSTRMAX);
if (err_str == NULL)
return -1;
va_start(argp, fmt);
vsnprintf(err_str, ERRSTRMAX-1, fmt, argp);
va_end(argp);
fprintf(stderr, "%s", err_str);
if (errno)
perror("perror says");
free(err_str);
if (!fatal)
return 0;
exit(fatal);
}
/* Subtract the `struct timeval' values X and Y,
storing the result in RESULT.
Return 1 if the difference is negative, otherwise 0. */
int timeval_subtract(struct timeval *result, struct timeval *x,
struct timeval *y)
{
/* Perform the carry for the later subtraction by updating y. */
if (x->tv_usec < y->tv_usec) {
int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1;
y->tv_usec -= 1000000 * nsec;
y->tv_sec += nsec;
}
if (x->tv_usec - y->tv_usec > 1000000) {
int nsec = (x->tv_usec - y->tv_usec) / 1000000;
y->tv_usec += 1000000 * nsec;
y->tv_sec -= nsec;
}
/* Compute the time remaining to wait.
tv_usec is certainly positive. */
result->tv_sec = x->tv_sec - y->tv_sec;
result->tv_usec = x->tv_usec - y->tv_usec;
/* Return 1 if result is negative. */
return x->tv_sec < y->tv_sec;
}
/*
* Converts decimal to binary.
* Credits: vegaseat. URL: http://www.daniweb.com/software-development/c/code/216349
* accepts a decimal integer and returns a binary coded string
*
* @decimal : decimal value to convert to binary (IN)
* @binary : the binary result as a string (OUT)
*
*/
void dec2bin(long decimal, char *binary)
{
int k = 0, n = 0;
int neg_flag = 0;
int remain;
/*
gcc 4.6.3 : we get the warning:
"warning: variable ‘old_decimal’ set but not used [-Wunused-but-set-variable]"
To get rid of this warning, have #ifdef'd the test... -kaiwan.
Keep one of the following below (wrt TESTMODE); comment out the other.
UN-defining by default.
*/
//#define TESTMODE
#undef TESTMODE
#ifdef TESTMODE
int old_decimal; // for test
#endif
char temp[80];
// take care of negative input
if (decimal < 0) {
decimal = -decimal;
neg_flag = 1;
}
do {
#ifdef TESTMODE
old_decimal = decimal; // for test
#endif
remain = decimal % 2;
// whittle down the decimal number
decimal = decimal / 2;
// this is a test to show the action
#ifdef TESTMODE
printf("%d/2 = %d remainder = %d\n", old_decimal, decimal,
remain);
#endif
// converts digit 0 or 1 to character '0' or '1'
temp[k++] = remain + '0';
} while (decimal > 0);
if (neg_flag)
temp[k++] = '-'; // add - sign
else
temp[k++] = ' '; // space
// reverse the spelling
while (k >= 0)
binary[n++] = temp[--k];
binary[n - 1] = 0; // end with NULL
}
/*
* function r _ s l e e p
*
* Wrapper around nanosleep(2) , and in such a way that interruption
* due to a non-blocked signals causes restart.
*/
#ifndef _TIME_H
#include <time.h>
#endif
int r_sleep(time_t sec, long nsec)
{
struct timespec req, rem;
req.tv_sec = sec;
req.tv_nsec = nsec;
while (nanosleep(&req, &rem) == -1) {
if (errno != EINTR)
return -1;
/* Actually should not use [f]printf in sig handler - not aysnc-signal
safe - just shown for demo purpose here (works with DEBUG option on).
Ugly!
*/
#ifdef DEBUG
fprintf(stderr,
"* nanosleep interrupted! rem time: %lu.%lu *\n",
rem.tv_sec, rem.tv_nsec);
#endif
req = rem;
}
return 0;
}
/*--------------- Sourced from:
http://www.alexonlinux.com/hex-dump-functions
All rights rest with original author(s).----------------------
Added a 'verbose' parameter..(kaiwan).
*/
void hex_dump(unsigned char *data, int size, char *caption, int verbose)
{
int i; // index in data...
int j; // index in line...
char temp[16];
char buffer[128];
char *ascii;
memset(buffer, 0, 128);
if (verbose && caption)
printf("---------> %s <--------- (%d bytes from %p)\n", caption,
size, data);
// Printing the ruler...
printf
(" +0 +4 +8 +c 0 4 8 c \n");
// Hex portion of the line is 8 (the padding) + 3 * 16 = 52 chars long
// We add another four bytes padding and place the ASCII version...
ascii = buffer + 58;
memset(buffer, ' ', 58 + 16);
buffer[58 + 16] = '\n';
buffer[58 + 17] = '\0';
buffer[0] = '+';
buffer[1] = '0';
buffer[2] = '0';
buffer[3] = '0';
buffer[4] = '0';
for (i = 0, j = 0; i < size; i++, j++) {
if (j == 16) {
printf("%s", buffer);
memset(buffer, ' ', 58 + 16);
sprintf(temp, "+%04x", i);
memcpy(buffer, temp, 5);
j = 0;
}
sprintf(temp, "%02x", 0xff & data[i]);
memcpy(buffer + 8 + (j * 3), temp, 2);
if ((data[i] > 31) && (data[i] < 127))
ascii[j] = data[i];
else
ascii[j] = '.';
}
if (j != 0)
printf("%s", buffer);
}
void Dprint(const char *fmt, ...)
{
va_list ap;
#ifdef DEBUG
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
#endif
}
/* vi: ts=8 */