source: bootcd/isolinux/syslinux-6.03/com32/modules/cptime.c

Last change on this file was e16e8f2, checked in by Edwin Eefting <edwin@datux.nl>, 3 years ago

bootstuff

  • Property mode set to 100644
File size: 8.0 KB
Line 
1/* ----------------------------------------------------------------------- *
2 *
3 *   Copyright 2010-2011 Gene Cumm
4 *
5 *   This program is free software; you can redistribute it and/or modify
6 *   it under the terms of the GNU General Public License as published by
7 *   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
8 *   Boston MA 02111-1307, USA; either version 2 of the License, or
9 *   (at your option) any later version; incorporated herein by reference.
10 *
11 * ----------------------------------------------------------------------- */
12
13/*
14 * cptime.c     Version 1.4
15 *
16 * Timed copy; read entire file then output total time, bytes transferred,
17 * and compute transfer rate.
18 *
19 * cptime [-s|-l] [-v|-q] [-b _SIZE_] [-n _LEN_] _FILE_...
20 *      -s      Change to simple output mode without computing transfer rate
21 *      -l      Change to long output mode (to allow for overriding previous -s)
22 *      -v      Verbose output
23 *      -q      Quiet output
24 *      -b _SIZE_       use _SIZE_ for transfer size
25 *      -n _LEN_        maximum length to fetch
26 *      _FILE_...       Space delimited list of files to dump
27 * Note: The last instance of -s or -l wins, along with the last use of -b and -n and the winning option will be applied to all operations
28 *
29 * Hisory:
30 * 1.4  Use fread() rather than read(); use CLK_TCK when available.
31 * 1.3  Added -v/-q; rework some argument processing.
32 * 1.2  Added -n
33 * 1.1  Added -l and -b switches; more flexible command line processing
34 * 1.0  First release
35 */
36
37/*
38 * ToDos:
39 * - Refine timing to be more precise.  Low priority.
40 * - Add -o for offset.  Wishlist.
41 */
42
43#include <stdio.h>
44#include <stdlib.h>
45#include <errno.h>
46#include <fcntl.h>
47#include <unistd.h>
48#include <sys/times.h>
49#include <consoles.h>
50#include <minmax.h>
51#include <limits.h>
52#include <string.h>
53#include <stdint.h>
54#include <console.h>
55
56#ifdef __COM32__
57#  define BUFSZ_DEF     (size_t)2048
58/* What's optimal?  Under 4k?
59 *      layout.inc: xfer_buf_seg        equ 1000h
60 *      com32.inc: push dword (1 << 16)         ; 64K bounce buffer
61 */
62/* typedef size_t off_t */
63
64#  define TPS_T float
65#  ifdef CLK_TCK
66static inline TPS_T get_tps(void) {     return CLK_TCK; }
67#  else
68static inline TPS_T get_tps(void) {     return 18.2;    }
69#  endif
70
71#else /* __COM32__ */
72
73#  define BUFSZ_DEF     (size_t)16384
74/* Need to check what might be a "best" buffer/fetch block size here */
75
76#  define TPS_T long
77static inline TPS_T get_tps(void) {     return sysconf(_SC_CLK_TCK);    }
78
79#endif /* __COM32__ */
80
81#ifndef SSIZE_MAX
82#  define SSIZE_MAX     PTRDIFF_MAX
83#endif
84/* typedef ptrdiff_t ssize_t; */
85#define BUFSZ_MAX       (size_t)SSIZE_MAX
86/* ssize_t max */
87#define BUFSZ_MIN       (size_t)1
88
89
90/* Please note: I don't know the origin of these two macros nor their license */
91#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
92#define TYPE_MAX(t) \
93  ((t) (! TYPE_SIGNED (t) \
94        ? (t) -1 \
95        : ~ (~ (t) 0 << (sizeof (t) * CHAR_BIT - 1))))
96
97#ifndef OFF_T_MAX
98#  define OFF_T_MAX     TYPE_MAX(off_t)
99#endif
100/* Can't be SIZE_MAX or SSIZE_MAX as Syslinux/COM32 is unsigned while Linux
101 * is signed.
102 */
103
104#define LEN_MAX         OFF_T_MAX
105/* off_t max */
106#define LEN_MIN         (off_t)0
107
108void print_cp_result_tick(size_t bcnt, clock_t et, TPS_T tps, int offs)
109{
110        size_t dr;
111        /* prevent divide by 0 */
112        dr = max(bcnt, (bcnt * tps)) / max((clock_t)1, (et + offs));
113        printf("  %+d %zu B/s; %zu KiB/s; %zu MiB/s\n", offs, dr, dr/1024, dr/1048576);
114}       /* void print_cp_result_tick(size_t bcnt, clock_t et, TPS_T tps, int offs) */
115
116void print_cp_result_long(char *fn, size_t bcnt, clock_t bc, clock_t ec, size_t bufsz, char do_verbose)
117{
118        TPS_T tps;
119        if (do_verbose > 2)
120                printf("Enter print_cp_result_long()\n");
121        tps = get_tps();
122        printf("  %zu B in %d ticks from '%s'\n", bcnt, (int)(ec - bc), fn);
123        printf("  ~%d ticks per second; %zu B block/transfer size\n", (int)tps, bufsz);
124        print_cp_result_tick(bcnt, (ec - bc), tps, 0);
125        print_cp_result_tick(bcnt, (ec - bc), tps, 1);
126        print_cp_result_tick(bcnt, (ec - bc), tps, -1);
127}       /* void print_cp_result_long(char *fn, size_t bcnt, clock_t bc, clock_t ec, size_t bufsz) */
128
129void print_cp_result_simple(char *fn, size_t bcnt, clock_t bc, clock_t ec, size_t bufsz, char do_verbose)
130{
131        if (do_verbose) {}
132        printf("  %zuB  %dt %zux '%s'\n", bcnt, (int)(ec - bc), bufsz, fn);
133}       /* void print_cp_result_simple(char *fn, int bcnt, clock_t bc, clock_t ec, char do_verbose) */
134
135size_t time_copy_bufsz(size_t bufsz, size_t bcnt, off_t maxlen)
136{
137        return min(bufsz, (maxlen - bcnt));
138}       /* size_t time_copy_bufsz(size_t bufsz, size_t bcnt, off_t maxlen) */
139
140int time_copy(char *fn, char do_simple, char do_verbose, size_t ibufsz, off_t maxlen)
141{
142//      int fd;
143        int rv = 0;
144        int i = 0;
145        FILE *f;
146        size_t bufsz, bcnt = 0;
147        int numrd;
148        struct tms tm;
149        clock_t bc, ec;
150        char buf[ibufsz + 1];
151
152        buf[0] = 0;
153        if (do_verbose)
154                printf("Trying file '%s'\n", fn);
155        errno = 0;
156//      fd = open(fn, O_RDONLY);
157        f = fopen(fn, "r");
158//      if (fd == -1) {
159        if (!f) {
160                switch (errno) {
161                case ENOENT :
162                        printf("File '%s' does not exist\n", fn);
163                        break;
164                case EBADF:
165                        printf("File '%s': Bad File Descriptor\n", fn);
166                        break;
167                default :
168                        printf("Error '%d' opening file '%s'\n", errno, fn);
169                }
170                rv = 1;
171        } else {
172                if (do_verbose)
173                        printf("File '%s' opened\n", fn);
174                bufsz = time_copy_bufsz(ibufsz, bcnt, maxlen);
175                bc = times(&tm);
176//              numrd = read(fd, buf, bufsz);
177//              numrd = fread(buf, bufsz, 1, f);
178                numrd = fread(buf, 1, bufsz, f);
179                i++;
180                if (numrd > 0)
181                        bcnt = numrd;
182                while ((numrd > 0) && (bufsz > 0)) {
183                        bufsz = time_copy_bufsz(bufsz, bcnt, maxlen);
184//                      numrd = read(fd, buf, bufsz);
185//                      numrd = fread(buf, bufsz, 1, f);
186                        numrd = fread(buf, 1, bufsz, f);
187                        i++;
188                        if (numrd >= 0)
189//                              bcnt = bcnt + numrd;
190                                bcnt += numrd;
191                }
192                ec = times(&tm);
193//              close(fd);
194                fclose(f);
195                if (do_verbose)
196                        printf("File '%s' closed\n", fn);
197                if (numrd < 0) {
198                        switch (errno) {
199                        case EIO :
200                                printf("IO Error at %zu B reading file '%s'\n", bcnt, fn);
201                                break;
202                        case EINVAL :
203                                printf("Invalid Mode at %zu B reading file '%s'\n", bcnt, fn);
204                                break;
205                        default :
206                                printf("Error '%d' at %zu B reading file '%s'\n", errno, bcnt, fn);
207                        }
208                        rv = 2;
209                }
210                if (bcnt > 0) {
211                        if (bufsz == 0)
212                                printf("maxed out on maxln\n");
213                        if (do_simple)
214                                print_cp_result_simple(fn, bcnt, bc, ec, ibufsz, do_verbose);
215                        else
216                                print_cp_result_long(fn, bcnt, bc, ec, ibufsz, do_verbose);
217                }
218                if (do_verbose)
219                        printf("  numrd %d bcnt %d bufsz %d i %d\n", numrd, bcnt, bufsz, i);
220        }
221        return rv;
222}       /* int time_copy(char *fn, char do_simple, int bufsz, off_t maxlen) */
223
224int main(int argc, char *argv[])
225{
226        int i;
227        char do_simple = 0, do_pbuf = 0, do_plen = 0, do_verbose = 0;
228        char *arg;
229        size_t tbufsz, bufsz = min((BUFSZ_DEF), (BUFSZ_MAX));
230        off_t tmaxlen, maxlen = LEN_MAX;
231        int numfl = 0;
232        console_ansi_std();
233//      openconsole(&dev_stdcon_r, &dev_stdcon_w);
234        for (i = 1; i < argc; i++) {
235                if (argv[i][0] == '-') {
236                        arg = argv[i] + 1;
237                        if (strcmp(arg, "b") == 0) {
238                                i++;
239                                if (i < argc) {
240                                        tbufsz = atoi(argv[i]);
241                                        if (tbufsz > 0)
242                                                bufsz = min(max((BUFSZ_MIN), tbufsz), (BUFSZ_MAX));
243                                        do_pbuf = 1;
244                                }
245                        } else if (strcmp(arg, "n") == 0) {
246                                i++;
247                                if (i < argc) {
248                                        tmaxlen = atoi(argv[i]);
249                                        if (tmaxlen > 0)
250                                                maxlen = min(max((LEN_MIN), tmaxlen), (LEN_MAX));
251                                        do_plen = 1;
252                                }
253                        } else if (strcmp(arg, "s") == 0)
254                                do_simple = 1;
255                        else if (strcmp(arg, "l") == 0)
256                                do_simple = 0;
257                        else if (strcmp(arg, "v") == 0)
258                                do_verbose = 1;
259                        else if (strcmp(arg, "q") == 0)
260                                do_verbose = 0;
261                }
262        }
263        if (do_pbuf || do_verbose)
264                printf("Using bufsz %zu\n", bufsz);
265        if (do_plen || do_verbose)
266                printf("Using maxlen %zu\n", maxlen);
267        for (i = 1; i < argc; i++) {
268                if (argv[i][0] == '-') {
269                        arg = argv[i] + 1;
270                        if ((strcmp(arg, "b") == 0) || (strcmp(arg, "n") == 0))
271                                i++;    /* Skip next arg */
272                        else if (!((strcmp(arg, "s") == 0) || (strcmp(arg, "l") == 0) || (strcmp(arg, "v") == 0) || (strcmp(arg, "q") == 0))) {
273                                time_copy(argv[i], do_simple, do_verbose, bufsz, maxlen);
274                                numfl++;
275                        }
276                } else {
277                        time_copy(argv[i], do_simple, do_verbose, bufsz, maxlen);
278                        numfl++;
279                }
280        }
281        if (numfl == 0)
282                fprintf(stderr, "%s: Please specify a file\n", argv[0]);
283        return 0;
284}       /* int main(int argc, char *argv[]) */
Note: See TracBrowser for help on using the repository browser.