source: lib/format_helper.c @ e1868fb

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since e1868fb was 4bd8a5b, checked in by Perry Lorier <perry@…>, 15 years ago

Cleanup a gazillion warnings

  • Property mode set to 100644
File size: 7.9 KB
Line 
1/*
2 * This file is part of libtrace
3 *
4 * Copyright (c) 2004 The University of Waikato, Hamilton, New Zealand.
5 * Authors: Daniel Lawson
6 *          Perry Lorier
7 *         
8 * All rights reserved.
9 *
10 * This code has been developed by the University of Waikato WAND
11 * research group. For further information please see http://www.wand.net.nz/
12 *
13 * libtrace is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * libtrace is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with libtrace; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26 *
27 * $Id$
28 *
29 */
30
31#include "config.h"
32#include <sys/types.h>
33#include <fcntl.h> /* for O_LARGEFILE */
34#include <math.h>
35#include "libtrace.h"
36#include "libtrace_int.h"
37
38#include <stdlib.h>
39#include <stdio.h>
40#include <string.h>
41#include <errno.h>
42#include "format_helper.h"
43
44#include <assert.h>
45#include <stdarg.h>
46
47#ifdef WIN32
48#  include <io.h>
49#  include <share.h>
50#  define snprintf sprintf_s
51
52struct libtrace_eventobj_t trace_event_device(struct libtrace_t *trace, struct libtrace_packet_t *packet) {
53    struct libtrace_eventobj_t event = {0,0,0.0,0};
54
55    trace_set_err(trace,TRACE_ERR_OPTION_UNAVAIL, "trace_event() is not "
56            "supported on devices under windows in this version");
57
58    event.type = TRACE_EVENT_TERMINATE;
59    return event;
60}
61#else
62#  include <sys/ioctl.h>
63
64struct libtrace_eventobj_t trace_event_device(struct libtrace_t *trace, 
65                                        struct libtrace_packet_t *packet) {
66        struct libtrace_eventobj_t event = {0,0,0.0,0};
67        int data;
68
69        assert(trace != NULL);
70        assert(packet != NULL);
71       
72        if (trace->format->get_fd) {
73                event.fd = trace->format->get_fd(trace);
74        } else {
75                event.fd = 0;
76        }
77        if (ioctl(event.fd,FIONREAD,&data)==-1) {
78                event.type = TRACE_EVENT_TERMINATE;
79                return event;
80        } 
81               
82        if (data>0) {
83                event.size = trace_read_packet(trace,packet);
84                event.type = TRACE_EVENT_PACKET;
85                return event;
86        }
87        event.type= TRACE_EVENT_IOWAIT;
88        return event;
89}
90#endif
91
92struct libtrace_eventobj_t trace_event_trace(struct libtrace_t *trace, struct libtrace_packet_t *packet) {
93        struct libtrace_eventobj_t event = {0,0,0.0,0};
94        double ts;
95        double now;
96        struct timeval stv;
97
98        if (!trace->event.packet) {
99                trace->event.packet = trace_create_packet();
100                trace->event.psize=
101                        trace_read_packet(trace,trace->event.packet);
102                if (trace->event.psize<1) {
103                        /* return here, the test for
104                         * event.size will sort out the error
105                         */
106                        if (trace_is_err(trace)) {
107                                trace_perror(trace, "read packet");
108                        }
109                        event.type = TRACE_EVENT_TERMINATE;
110                        return event;
111                }
112        }
113
114        ts=trace_get_seconds(trace->event.packet);
115        if (fabs(trace->event.tdelta)<1e-9) {
116                /* Get the adjusted current time */
117                gettimeofday(&stv, NULL);
118                now = stv.tv_sec + 
119                        ((double)stv.tv_usec / 1000000.0);
120                /* adjust for trace delta */
121                now -= trace->event.tdelta; 
122
123                /* if the trace timestamp is still in the
124                 * future, return a SLEEP event,
125                 * otherwise fire the packet
126                 */
127                if (ts > now) {
128                        event.seconds = ts - 
129                                trace->event.trace_last_ts;
130                        event.type = TRACE_EVENT_SLEEP;
131                        return event;
132                }
133        } else {
134                gettimeofday(&stv, NULL);
135                /* work out the difference between the
136                 * start of trace replay, and the first
137                 * packet in the trace
138                 */
139                trace->event.tdelta = stv.tv_sec + 
140                        ((double)stv.tv_usec / 1000000.0);
141                trace->event.tdelta -= ts;
142        }
143
144        /* This is the first packet, so just fire away. */
145        /* TODO: finalise packet */
146       
147        /* XXX: Could we do this more efficiently? */
148        /* We do a lot of freeing and creating of packet buffers with this
149         * method, but at least it works unlike what was here previously */
150        if (packet->buf_control == TRACE_CTRL_PACKET) {
151                free(packet->buffer);
152        }
153               
154        packet->type = trace->event.packet->type;
155        packet->trace = trace->event.packet->trace;
156        packet->header = trace->event.packet->header;
157        packet->payload = trace->event.packet->payload;
158       
159        packet->buffer = trace->event.packet->buffer;
160        packet->buf_control = trace->event.packet->buf_control;
161
162        trace->event.packet->buf_control = TRACE_CTRL_EXTERNAL;
163       
164        trace_destroy_packet(trace->event.packet);
165        trace->event.packet = NULL;
166
167        event.type = TRACE_EVENT_PACKET;
168
169        trace->event.trace_last_ts = ts;
170
171        return event;
172}
173
174/* Catch undefined O_LARGEFILE on *BSD etc */
175#ifndef O_LARGEFILE
176#  define O_LARGEFILE 0
177#endif
178
179/* Catching O_BINARY on all sane OS's */
180#ifndef O_BINARY
181#  define O_BINARY 0
182#endif
183
184/* open a file or stdin using gzip compression if necessary (and supported)
185 * @internal
186 */
187libtrace_io_t *trace_open_file(libtrace_t *trace)
188{
189        int fd;
190        libtrace_io_t *ret;
191
192
193        if (strcmp(trace->uridata,"-")==0) {
194                ret=libtrace_io_fdopen(fileno(stdin),"rb");
195                return ret;
196        }
197
198        /* We open the file with open(2), so we can provide O_LARGEFILE
199         * as zlib doesn't always do it itself
200         */
201        fd=open(trace->uridata,O_LARGEFILE|O_RDONLY|O_BINARY);
202        if (fd==-1) {
203                trace_set_err(trace,errno,"Unable to open %s",trace->uridata);
204                return 0;
205        }
206        ret=libtrace_io_fdopen(fd,"rb");
207        return ret;
208}
209
210/* Create a file or write to stdout using compression if requested
211 * @internal
212 */
213libtrace_io_t *trace_open_file_out(libtrace_out_t *trace,int level, int fileflag)
214{
215        int fd;
216        libtrace_io_t *ret;
217        char filemode[4]; /* wb9\0 */
218        assert(level<10);
219        assert(level>=0);
220#ifdef HAVE_LIBZ
221        snprintf(filemode,sizeof(filemode),"wb%d",level);
222#else
223        snprintf(filemode,sizeof(filemode),"wb");
224#endif
225
226        if (strcmp(trace->uridata,"-")==0) {
227                ret=libtrace_io_fdopen(fileno(stdout),filemode);
228                return ret;
229        }
230
231        /* We open the file with open(2), so we can provide O_LARGEFILE
232         * as zlib doesn't always do it itself
233         */
234        fd=open(trace->uridata,fileflag|O_LARGEFILE|O_BINARY,0666);
235        if (fd==-1) {
236                trace_set_err_out(trace,
237                                errno,"Unable to open %s",trace->uridata);
238                return 0;
239        }
240        ret=libtrace_io_fdopen(fd,filemode);
241        if (!ret) {
242                printf("%s\n",filemode);
243                trace_set_err_out(trace,
244                                TRACE_ERR_INIT_FAILED,"gz out of memory");
245        }
246        return ret;
247}
248
249
250/** Update the libtrace error
251 * @param errcode either an Econstant from libc, or a LIBTRACE_ERROR
252 * @param msg a plaintext error message
253 * @internal
254 */
255void trace_set_err(libtrace_t *trace,int errcode,const char *msg,...)
256{
257        char buf[256];
258        va_list va;
259        va_start(va,msg);
260        assert(errcode != 0 && "An error occurred, but it is unknown what it is");
261        trace->err.err_num=errcode;
262        if (errcode>0) {
263                vsnprintf(buf,sizeof(buf),msg,va);
264                snprintf(trace->err.problem,sizeof(trace->err.problem),
265                                "%s: %s",buf,strerror(errcode));
266        } else {
267                vsnprintf(trace->err.problem,sizeof(trace->err.problem),
268                                msg,va);
269        }
270        va_end(va);
271}
272
273/** Update the libtrace for output traces error
274 * @param errcode either an Econstant from libc, or a LIBTRACE_ERROR
275 * @param msg a plaintext error message
276 * @internal
277 */
278void trace_set_err_out(libtrace_out_t *trace,int errcode,const char *msg,...)
279{
280        char buf[256];
281        va_list va;
282        va_start(va,msg);
283        assert(errcode != 0 && "An error occurred, but it is unknown what it is");
284        trace->err.err_num=errcode;
285        if (errcode>0) {
286                vsnprintf(buf,sizeof(buf),msg,va);
287                snprintf(trace->err.problem,sizeof(trace->err.problem),
288                                "%s: %s",buf,strerror(errno));
289        } else {
290                vsnprintf(trace->err.problem,sizeof(trace->err.problem),
291                                msg,va);
292        }
293        va_end(va);
294}
295
296uint64_t byteswap64(uint64_t num)
297{
298        return (byteswap32((num&0xFFFFFFFF00000000ULL)>>32))
299              |((uint64_t)byteswap32(num&0x00000000FFFFFFFFULL)<<32);
300}
301
302uint32_t byteswap32(uint32_t num)
303{
304        return ((num&0x000000FFU)<<24)
305                | ((num&0x0000FF00U)<<8)
306                | ((num&0x00FF0000U)>>8)
307                | ((num&0xFF000000U)>>24);
308}
309
310uint16_t byteswap16(uint16_t num)
311{
312        return ((num<<8)&0xFF00)|((num>>8)&0x00FF);
313}
314
Note: See TracBrowser for help on using the repository browser.