source: lib/format_helper.c @ 8bef018

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

Use binary i/o mode to keep windows backwardsness happy

  • Property mode set to 100644
File size: 6.5 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/* open a file or stdin using gzip compression if necessary (and supported)
157 * @internal
158 */
159libtrace_io_t *trace_open_file(libtrace_t *trace)
160{
161        int fd;
162        libtrace_io_t *ret;
163
164
165        if (strcmp(trace->uridata,"-")==0) {
166                ret=libtrace_io_fdopen(fileno(stdin),"r");
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         */
173        fd=open(trace->uridata,O_LARGEFILE|O_RDONLY);
174        if (fd==-1) {
175                trace_set_err(trace,errno,"Unable to open %s",trace->uridata);
176                return 0;
177        }
178        ret=libtrace_io_fdopen(fd,"rb");
179        return ret;
180}
181
182/* Create a file or write to stdout using compression if requested
183 * @internal
184 */
185libtrace_io_t *trace_open_file_out(libtrace_out_t *trace,int level, int fileflag)
186{
187        int fd;
188        libtrace_io_t *ret;
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,"wb");
196#endif
197
198        if (strcmp(trace->uridata,"-")==0) {
199                ret=libtrace_io_fdopen(fileno(stdout),filemode);
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         */
206        fd=open(trace->uridata,fileflag|O_LARGEFILE,0666);
207        if (fd==-1) {
208                trace_set_err_out(trace,
209                                errno,"Unable to open %s",trace->uridata);
210                return 0;
211        }
212        ret=libtrace_io_fdopen(fd,filemode);
213        if (!ret) {
214                printf("%s\n",filemode);
215                trace_set_err_out(trace,
216                                TRACE_ERR_INIT_FAILED,"gz out of memory");
217        }
218        return ret;
219}
220
221
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}
265
Note: See TracBrowser for help on using the repository browser.