source: lib/format_helper.c @ e2aebe7

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

Change the API for filters to

trace_create_filter
trace_apply_filter
trace_destroy_filter

Also, cleanup bitfield issues with msvc/gcc

  • Property mode set to 100644
File size: 6.8 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 "libtrace.h"
35#include "libtrace_int.h"
36
37#include <stdlib.h>
38#include <stdio.h>
39#include <string.h>
40#include <errno.h>
41#include "format_helper.h"
42
43#include <assert.h>
44#include <stdarg.h>
45
46#ifdef WIN32
47#  include <io.h>
48#  include <share.h>
49#  define snprintf sprintf_s
50
51struct libtrace_eventobj_t trace_event_device(struct libtrace_t *trace, struct libtrace_packet_t *packet) {
52    struct libtrace_eventobj_t event = {0,0,0.0,0};
53
54    trace_set_err(trace,TRACE_ERR_OPTION_UNAVAIL, "trace_event() is not "
55            "supported on devices under windows in this version");
56
57    event.type = TRACE_EVENT_TERMINATE;
58    return event;
59}
60#else
61#  include <sys/ioctl.h>
62
63struct libtrace_eventobj_t trace_event_device(struct libtrace_t *trace, struct libtrace_packet_t *packet) {
64        struct libtrace_eventobj_t event = {0,0,0.0,0};
65        int data;
66
67        assert(trace);
68        assert(packet);
69       
70        if (trace->format->get_fd) {
71                event.fd = trace->format->get_fd(trace);
72        } else {
73                event.fd = 0;
74        }
75        if (ioctl(event.fd,FIONREAD,&data)==-1) {
76                event.type = TRACE_EVENT_TERMINATE;
77                return event;
78        } 
79               
80        if (data>0) {
81                event.size = trace_read_packet(trace,packet);
82                event.type = TRACE_EVENT_PACKET;
83                return event;
84        }
85        event.type= TRACE_EVENT_IOWAIT;
86        return event;
87}
88#endif
89
90struct libtrace_eventobj_t trace_event_trace(struct libtrace_t *trace, struct libtrace_packet_t *packet) {
91        struct libtrace_eventobj_t event = {0,0,0.0,0};
92        double ts;
93        double now;
94        struct timeval stv;
95
96        if (!trace->event.packet) {
97                trace->event.packet = trace_create_packet();
98                trace->event.psize=
99                        trace_read_packet(trace,trace->event.packet);
100                if (trace->event.psize<1) {
101                        /* return here, the test for
102                         * event.size will sort out the error
103                         */
104                        event.type = TRACE_EVENT_TERMINATE;
105                        return event;
106                }
107        }
108
109        ts=trace_get_seconds(trace->event.packet);
110        if (trace->event.tdelta!=0) {
111                /* Get the adjusted current time */
112                gettimeofday(&stv, NULL);
113                now = stv.tv_sec + 
114                        ((double)stv.tv_usec / 1000000.0);
115                /* adjust for trace delta */
116                now -= trace->event.tdelta; 
117
118                /* if the trace timestamp is still in the
119                 * future, return a SLEEP event,
120                 * otherwise fire the packet
121                 */
122                if (ts > now) {
123                        event.seconds = ts - 
124                                trace->event.trace_last_ts;
125                        event.type = TRACE_EVENT_SLEEP;
126                        return event;
127                }
128        } else {
129                gettimeofday(&stv, NULL);
130                /* work out the difference between the
131                 * start of trace replay, and the first
132                 * packet in the trace
133                 */
134                trace->event.tdelta = stv.tv_sec + 
135                        ((double)stv.tv_usec / 1000000.0);
136                trace->event.tdelta -= ts;
137        }
138
139        /* This is the first packet, so just fire away. */
140        /* TODO: finalise packet */
141        *packet = *trace->event.packet;
142        trace_destroy_packet(trace->event.packet);
143        trace->event.packet = NULL;
144
145        event.type = TRACE_EVENT_PACKET;
146
147        trace->event.trace_last_ts = ts;
148
149        return event;
150}
151
152/* Catch undefined O_LARGEFILE on *BSD etc */
153#ifndef O_LARGEFILE
154#  define O_LARGEFILE 0
155#endif
156
157/* Catching O_BINARY on all sane OS's */
158#ifndef O_BINARY
159#  define O_BINARY 0
160#endif
161
162/* open a file or stdin using gzip compression if necessary (and supported)
163 * @internal
164 */
165libtrace_io_t *trace_open_file(libtrace_t *trace)
166{
167        int fd;
168        libtrace_io_t *ret;
169
170
171        if (strcmp(trace->uridata,"-")==0) {
172                ret=libtrace_io_fdopen(fileno(stdin),"rb");
173                return ret;
174        }
175
176        /* We open the file with open(2), so we can provide O_LARGEFILE
177         * as zlib doesn't always do it itself
178         */
179        fd=open(trace->uridata,O_LARGEFILE|O_RDONLY|O_BINARY);
180        if (fd==-1) {
181                trace_set_err(trace,errno,"Unable to open %s",trace->uridata);
182                return 0;
183        }
184        ret=libtrace_io_fdopen(fd,"rb");
185        return ret;
186}
187
188/* Create a file or write to stdout using compression if requested
189 * @internal
190 */
191libtrace_io_t *trace_open_file_out(libtrace_out_t *trace,int level, int fileflag)
192{
193        int fd;
194        libtrace_io_t *ret;
195        char filemode[4]; /* wb9\0 */
196        assert(level<10);
197        assert(level>=0);
198#if HAVE_ZLIB
199        sprintf(filemode,"wb%d",level);
200#else
201        sprintf(filemode,"wb");
202#endif
203
204        if (strcmp(trace->uridata,"-")==0) {
205                ret=libtrace_io_fdopen(fileno(stdout),filemode);
206                return ret;
207        }
208
209        /* We open the file with open(2), so we can provide O_LARGEFILE
210         * as zlib doesn't always do it itself
211         */
212        fd=open(trace->uridata,fileflag|O_LARGEFILE|O_BINARY,0666);
213        if (fd==-1) {
214                trace_set_err_out(trace,
215                                errno,"Unable to open %s",trace->uridata);
216                return 0;
217        }
218        ret=libtrace_io_fdopen(fd,filemode);
219        if (!ret) {
220                printf("%s\n",filemode);
221                trace_set_err_out(trace,
222                                TRACE_ERR_INIT_FAILED,"gz out of memory");
223        }
224        return ret;
225}
226
227
228/** Update the libtrace error
229 * @param errcode either an Econstant from libc, or a LIBTRACE_ERROR
230 * @param msg a plaintext error message
231 * @internal
232 */
233void trace_set_err(libtrace_t *trace,int errcode,const char *msg,...)
234{
235        char buf[256];
236        va_list va;
237        va_start(va,msg);
238        assert(errcode != 0 && "An error occurred, but it is unknown what it is");
239        trace->err.err_num=errcode;
240        if (errcode>0) {
241                vsnprintf(buf,sizeof(buf),msg,va);
242                snprintf(trace->err.problem,sizeof(trace->err.problem),
243                                "%s: %s",buf,strerror(errcode));
244        } else {
245                vsnprintf(trace->err.problem,sizeof(trace->err.problem),
246                                msg,va);
247        }
248        va_end(va);
249}
250
251/** Update the libtrace for output traces error
252 * @param errcode either an Econstant from libc, or a LIBTRACE_ERROR
253 * @param msg a plaintext error message
254 * @internal
255 */
256void trace_set_err_out(libtrace_out_t *trace,int errcode,const char *msg,...)
257{
258        char buf[256];
259        va_list va;
260        va_start(va,msg);
261        assert(errcode != 0 && "An error occurred, but it is unknown what it is");
262        trace->err.err_num=errcode;
263        if (errcode>0) {
264                vsnprintf(buf,sizeof(buf),msg,va);
265                snprintf(trace->err.problem,sizeof(trace->err.problem),
266                                "%s: %s",buf,strerror(errno));
267        } else {
268                vsnprintf(trace->err.problem,sizeof(trace->err.problem),
269                                msg,va);
270        }
271        va_end(va);
272}
273
Note: See TracBrowser for help on using the repository browser.