source: lib/format_helper.c @ 0ea3526

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

Add new error handling

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