source: lib/format_helper.c @ b333d68

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

Report buggy trace_set_err's for future

  • 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->event.packet = NULL;
143
144        event.type = TRACE_EVENT_PACKET;
145
146        trace->event.trace_last_ts = ts;
147
148        return event;
149}
150
151/* Catch undefined O_LARGEFILE on *BSD etc */
152#ifndef O_LARGEFILE
153#  define O_LARGEFILE 0
154#endif
155
156/* Catching O_BINARY on all sane OS's */
157#ifndef O_BINARY
158#  define O_BINARY 0
159#endif
160
161/* open a file or stdin using gzip compression if necessary (and supported)
162 * @internal
163 */
164libtrace_io_t *trace_open_file(libtrace_t *trace)
165{
166        int fd;
167        libtrace_io_t *ret;
168
169
170        if (strcmp(trace->uridata,"-")==0) {
171                ret=libtrace_io_fdopen(fileno(stdin),"r");
172                return ret;
173        }
174
175        /* We open the file with open(2), so we can provide O_LARGEFILE
176         * as zlib doesn't always do it itself
177         */
178        fd=open(trace->uridata,O_LARGEFILE|O_RDONLY|O_BINARY);
179        if (fd==-1) {
180                trace_set_err(trace,errno,"Unable to open %s",trace->uridata);
181                return 0;
182        }
183        ret=libtrace_io_fdopen(fd,"rb");
184        return ret;
185}
186
187/* Create a file or write to stdout using compression if requested
188 * @internal
189 */
190libtrace_io_t *trace_open_file_out(libtrace_out_t *trace,int level, int fileflag)
191{
192        int fd;
193        libtrace_io_t *ret;
194        char filemode[4]; /* wb9\0 */
195        assert(level<10);
196        assert(level>=0);
197#if HAVE_ZLIB
198        sprintf(filemode,"wb%d",level);
199#else
200        sprintf(filemode,"wb");
201#endif
202
203        if (strcmp(trace->uridata,"-")==0) {
204                ret=libtrace_io_fdopen(fileno(stdout),filemode);
205                return ret;
206        }
207
208        /* We open the file with open(2), so we can provide O_LARGEFILE
209         * as zlib doesn't always do it itself
210         */
211        fd=open(trace->uridata,fileflag|O_LARGEFILE|O_BINARY,0666);
212        if (fd==-1) {
213                trace_set_err_out(trace,
214                                errno,"Unable to open %s",trace->uridata);
215                return 0;
216        }
217        ret=libtrace_io_fdopen(fd,filemode);
218        if (!ret) {
219                printf("%s\n",filemode);
220                trace_set_err_out(trace,
221                                TRACE_ERR_INIT_FAILED,"gz out of memory");
222        }
223        return ret;
224}
225
226
227/** Update the libtrace error
228 * @param errcode either an Econstant from libc, or a LIBTRACE_ERROR
229 * @param msg a plaintext error message
230 * @internal
231 */
232void trace_set_err(libtrace_t *trace,int errcode,const char *msg,...)
233{
234        char buf[256];
235        va_list va;
236        va_start(va,msg);
237        assert(errcode != 0 && "An error occurred, but it is unknown what it is");
238        trace->err.err_num=errcode;
239        if (errcode>0) {
240                vsnprintf(buf,sizeof(buf),msg,va);
241                snprintf(trace->err.problem,sizeof(trace->err.problem),
242                                "%s: %s",buf,strerror(errno));
243        } else {
244                vsnprintf(trace->err.problem,sizeof(trace->err.problem),
245                                msg,va);
246        }
247        va_end(va);
248}
249
250/** Update the libtrace for output traces 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_out(libtrace_out_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(errno));
266        } else {
267                vsnprintf(trace->err.problem,sizeof(trace->err.problem),
268                                msg,va);
269        }
270        va_end(va);
271}
272
Note: See TracBrowser for help on using the repository browser.