source: lib/format_helper.c @ 9c4b5e3

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

Added support for nonblocking events for format_rt

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