source: tools/tracemerge/tracemerge.c @ 2cf30f6

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

Add signal handling to more programs that could use it.

  • Property mode set to 100644
File size: 3.4 KB
Line 
1#include <libtrace.h>
2#include <stdio.h>
3#include <stdlib.h>
4#include <inttypes.h>
5#include <stdbool.h>
6#include <getopt.h>
7#include <signal.h>
8
9static void usage(char *argv0)
10{
11        fprintf(stderr,"Usage:\n"
12        "%s flags outputuri traceuri [traceuri...]\n"
13        "-i --set-interface     Each trace is allocated an interface. Default leaves this flag as read from the original traces, if appropriate\n"
14        "-u --unique-packets    Discard duplicate packets\n"
15        "-H --libtrace-help     Print libtrace runtime documentation\n"
16        ,argv0);
17        exit(1);
18}
19
20volatile int done=0;
21
22static void cleanup_signal(int sig)
23{
24        done=1;
25}
26
27int main(int argc, char *argv[])
28{
29       
30        struct libtrace_out_t *output;
31        struct libtrace_t **input;
32        struct libtrace_packet_t **packet;
33        bool *live;
34        bool set_interface=false;
35        bool unique_packets=false;
36        int i=0;
37        uint64_t last_ts=0;
38        struct sigaction sigact;
39
40        while (1) {
41                int option_index;
42                struct option long_options[] = {
43                        { "set-interface",      0, 0, 'i' },
44                        { "unique-packets",     0, 0, 'u' },
45                        { "libtrace-help",      0, 0, 'H' },
46                        { NULL,                 0, 0, 0   },
47                };
48
49                int c=getopt_long(argc, argv, "iuH",
50                                long_options, &option_index);
51
52                if (c==-1)
53                        break;
54
55                switch (c) {
56                        case 'i': set_interface=true; break;
57                        case 'u': unique_packets=true; break;
58                        case 'H':
59                                  trace_help();
60                                  exit(1);
61                                  break;
62                        default:
63                                fprintf(stderr,"unknown option: %c\n",c);
64                                usage(argv[0]);
65
66                }
67
68        }
69
70        if (optind+2>argc)
71                usage(argv[0]);
72
73        output=trace_create_output(argv[optind++]);
74        if (trace_is_err_output(output)) {
75                trace_perror_output(output,"trace_create_output");
76                return 1;
77        }
78        if (trace_start_output(output)==-1) {
79                trace_perror_output(output,"trace_start_output");
80                return 1;
81        }
82
83        sigact.sa_handler = cleanup_signal;
84        sigemptyset(&sigact.sa_mask);
85        sigact.sa_flags = SA_RESTART;
86
87        sigaction(SIGINT,&sigact,NULL);
88        sigaction(SIGTERM,&sigact,NULL);
89
90        input=calloc((size_t)(argc-optind),sizeof(struct libtrace_t *));
91        packet=calloc((size_t)(argc-optind),sizeof(struct libtrace_packet_t *));
92        live=calloc((size_t)(argc-optind),sizeof(bool));
93        for(i=0;i<argc-optind;++i) {
94                libtrace_t *f;
95                libtrace_packet_t *p;
96                f=trace_create(argv[i+optind]);
97                if (trace_is_err(f)) {
98                        trace_perror(f,"trace_create");
99                        return 1;
100                }
101                if (trace_start(f)==-1) {
102                        trace_perror(f,"trace_start");
103                        return 1;
104                }
105                p=trace_create_packet();
106                input[i]=f;
107                packet[i]=p;
108                if (trace_read_packet(f,packet[i])>0)
109                        live[i]=true;
110        }
111
112        while(1) {
113                uint64_t oldest_ts=0;
114                int oldest=-1;
115                if (done)
116                        break;
117                for(i=0;i<argc-optind;++i) {
118                        if (!live[i] && input[i]) {
119                                int ret=trace_read_packet(input[i],packet[i]);
120                                if (ret<0) {
121                                        /* Error */
122                                        perror(argv[i+2]);
123                                        trace_destroy(input[i]);
124                                        input[i]=NULL;
125                                }
126                                else if (ret==0) {
127                                        /* EOF */
128                                        trace_destroy(input[i]);
129                                        input[i]=NULL;
130                                }
131                                else
132                                        live[i]=true;
133                        }
134                        if (live[i] && 
135                                (oldest==-1 || 
136                                 oldest_ts>trace_get_erf_timestamp(packet[i]))) {
137                                oldest=i;
138                                oldest_ts=trace_get_erf_timestamp(packet[i]);
139                        }
140                }
141                /* We have run out of packets! */
142                if (oldest==-1) {
143                        break;
144                }
145
146                live[oldest]=false;
147
148                if (set_interface)
149                        trace_set_direction(packet[oldest],oldest);
150
151                if (unique_packets && oldest_ts == last_ts)
152                        continue;
153
154                if (trace_write_packet(output,packet[oldest]) < 0) {
155                        trace_perror_output(output, "trace_write_packet");
156                        break;
157                }
158
159                last_ts=oldest_ts;
160               
161        }
162        trace_destroy_output(output);
163
164        return 0;
165}
Note: See TracBrowser for help on using the repository browser.