source: lib/format_helper.c @ 23971d0

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

Portability fixes for windows

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