source: lib/format_helper.c @ eeab9832

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

Fix problems with largefile support

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