source: lib/format_helper.c @ edb18ce

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

Rewrote libtrace's IO handling to use shim functions when needing to do
zlib io

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