]>
Commit | Line | Data |
---|---|---|
756bf715 | 1 | --- buffer-1.19.orig/buffer.man |
2 | +++ buffer-1.19/buffer.man | |
3 | @@ -37,7 +37,8 @@ | |
4 | Use the given file as the output file. The default is stdout. | |
5 | .TP | |
6 | .B \-S size | |
7 | -After every chunk this size has been writen print out how much been writen so far. | |
8 | +After every chunk of this size has been written, print out how much has | |
9 | +been written so far. Also prints the total througput. | |
10 | By default this is not set. | |
11 | .TP | |
12 | .B \-s size | |
13 | @@ -71,9 +72,9 @@ | |
14 | throughput on some drives.) | |
15 | .TP | |
16 | .B \-B | |
17 | -Force each block writen to be padded out to the blocksize. This is needed by some tape | |
18 | +Force each block written to be padded out to the blocksize. This is needed by some tape | |
19 | and cartridge drives. Defaults to unpadded. This only affects the | |
20 | -last block writen. | |
21 | +last block written. | |
22 | .TP | |
23 | .B \-t | |
24 | On exiting print to stderr a brief message showing the total number of | |
25 | @@ -82,7 +83,7 @@ | |
26 | .B \-Z | |
27 | If reading/writing directly to a character device (like a tape drive) | |
28 | then after each gigabyte perform an lseek to the start of the file. | |
29 | -Use this flag with extreme care. If can only be used on devices where | |
30 | +Use this flag with extreme care. It can only be used on devices where | |
31 | an lseek does not rewind the tape but does reset the kernels position | |
32 | flags. It is used to allow more than 2 gigabytes to be written. | |
33 | .PP | |
34 | --- buffer-1.19.orig/buffer.c | |
35 | +++ buffer-1.19/buffer.c | |
36 | @@ -78,7 +78,7 @@ | |
37 | * Christoph Wicki <wicki@iis.ethz.ch> | |
38 | * | |
39 | * Revision 1.7 1992/07/23 20:42:03 lmjm | |
40 | - * Added 't' option to print total writen at end. | |
41 | + * Added 't' option to print total written at end. | |
42 | * | |
43 | * Revision 1.6 1992/04/07 19:57:30 lmjm | |
44 | * Added Kevins -B and -p options. | |
45 | @@ -93,7 +93,7 @@ | |
46 | * Make sofar printing size an option. | |
47 | * | |
48 | * Revision 1.3 90/05/15 23:27:46 lmjm | |
49 | - * Added -S option (show how much has been writen). | |
50 | + * Added -S option (show how much has been written). | |
51 | * Added -m option to specify how much shared memory to grab. | |
52 | * Now tries to fill this with blocks. | |
53 | * reader waits for writer to terminate and then frees the shared mem and sems. | |
54 | @@ -109,6 +109,9 @@ | |
55 | * Initial revision | |
56 | * | |
57 | */ | |
58 | +#include <stdlib.h> | |
59 | +#include <string.h> | |
60 | +#include <limits.h> | |
61 | #include <unistd.h> | |
62 | #include <stdio.h> | |
63 | #include <signal.h> | |
64 | @@ -120,15 +123,16 @@ | |
65 | #include <sys/shm.h> | |
66 | #include <sys/sem.h> | |
67 | #include <sys/wait.h> | |
68 | +#include <sys/time.h> | |
69 | #include "sem.h" | |
70 | ||
71 | #ifndef lint | |
91c9e226 | 72 | static char *rcsid = "$Header: /a/swan/home/swan/staff/csg/lmjm/src/buffer/RCS/buffer.c,v 1.19 1995/08/24 17:46:28 lmjm Exp lmjm $"; |
756bf715 | 73 | #endif |
74 | ||
75 | -#ifndef __alpha | |
76 | +#ifndef __linux__ | |
77 | extern char *shmat(); | |
78 | -#endif /* __alpha */ | |
79 | +#endif /* __linux__ */ | |
80 | ||
81 | /* General macros */ | |
82 | #define TRUE 1 | |
83 | @@ -136,6 +140,14 @@ | |
84 | #define K *1024 | |
85 | #define M *1024*1024 | |
86 | ||
87 | +#if defined __GNUC__ || __STDC_VERSION__ >= 199901L | |
88 | +#define NUM_K_TYPE unsigned long long | |
89 | +#define NUM_K_FMT "llu" | |
90 | +#else | |
91 | +#define NUM_K_TYPE unsigned long | |
92 | +#define NUM_K_FMT "lu" | |
93 | +#endif | |
94 | + | |
95 | /* Some forward declarations */ | |
96 | void byee(); | |
97 | void start_reader_and_writer(); | |
98 | @@ -159,7 +171,7 @@ | |
99 | void pr_out(); | |
100 | void end_writer(); | |
101 | ||
102 | -/* When showing print a note every this many bytes writen */ | |
103 | +/* When showing print a note every this many bytes written */ | |
104 | int showevery = 0; | |
105 | #define PRINT_EVERY 10 K | |
106 | ||
107 | @@ -250,7 +262,9 @@ | |
108 | ||
109 | char print_total = 0; | |
110 | /* Number of K output */ | |
111 | -unsigned long outk = 0; | |
112 | +NUM_K_TYPE outk = 0; | |
113 | + | |
114 | +struct timeval starttime; | |
115 | ||
116 | int | |
117 | main( argc, argv ) | |
118 | @@ -262,6 +276,8 @@ | |
119 | set_handlers(); | |
120 | ||
121 | buffer_allocate(); | |
122 | + | |
123 | + gettimeofday(&starttime, NULL); | |
124 | ||
125 | start_reader_and_writer(); | |
126 | ||
127 | @@ -287,7 +303,7 @@ | |
128 | ||
129 | while( (c = getopt( argc, argv, "BS:Zdm:s:b:p:u:ti:o:z:" )) != -1 ){ | |
130 | switch( c ){ | |
131 | - case 't': /* Print to stderr the total no of bytes writen */ | |
132 | + case 't': /* Print to stderr the total no of bytes written */ | |
133 | print_total++; | |
134 | break; | |
135 | case 'u': /* pause after write for given microseconds */ | |
136 | @@ -384,8 +400,8 @@ | |
137 | fprintf( stderr, "Usage: %s [-B] [-t] [-S size] [-m memsize] [-b blocks] [-p percent] [-s blocksize] [-u pause] [-i infile] [-o outfile] [-z size]\n", | |
138 | progname ); | |
139 | fprintf( stderr, "-B = blocked device - pad out last block\n" ); | |
140 | - fprintf( stderr, "-t = show total amount writen at end\n" ); | |
141 | - fprintf( stderr, "-S size = show amount writen every size bytes\n" ); | |
142 | + fprintf( stderr, "-t = show total amount written at end\n" ); | |
143 | + fprintf( stderr, "-S size = show amount written every size bytes\n" ); | |
144 | fprintf( stderr, "-m size = size of shared mem chunk to grab\n" ); | |
145 | fprintf( stderr, "-b num = number of blocks in queue\n" ); | |
146 | fprintf( stderr, "-p percent = don't start writing until percent blocks filled\n" ); | |
147 | @@ -397,6 +413,11 @@ | |
148 | byee( -1 ); | |
149 | } | |
150 | } | |
151 | + | |
152 | + if (argc > optind) { | |
153 | + fprintf( stderr, "too many arguments\n" ); | |
154 | + byee( -1 ); | |
155 | + } | |
156 | ||
157 | if (zflag) showevery = blocksize; | |
158 | ||
159 | @@ -507,9 +528,9 @@ | |
160 | get_buffer(); | |
161 | ||
162 | if( debug ) | |
163 | - fprintf( stderr, "%s pbuffer is 0x%08x, buffer_size is %d [%d x %d]\n", | |
164 | + fprintf( stderr, "%s pbuffer is 0x%08lx, buffer_size is %d [%d x %d]\n", | |
165 | proc_string, | |
166 | - (char *)pbuffer, buffer_size, blocks, blocksize ); | |
167 | + (unsigned long)pbuffer, buffer_size, blocks, blocksize ); | |
168 | ||
169 | #ifdef SYS5 | |
170 | memset( (char *)pbuffer, '\0', buffer_size ); | |
171 | @@ -528,7 +549,17 @@ | |
172 | pbuffer->blocks_free_lock = 1; | |
173 | /* start this off so lock() can be called on it for each block | |
174 | * till all the blocks are used up */ | |
175 | + /* Initializing the semaphore to "blocks - 1" causes a hang when using option | |
176 | + * "-p 100" because it always keeps one block free, so we'll never reach 100% fill | |
177 | + * level. However, there doesn't seem to be a good reason to keep one block free, | |
178 | + * so we initialize the semaphore to "blocks" instead. | |
179 | + * <mbuck@debian.org> 2004-01-11 | |
180 | + */ | |
181 | +#if 0 | |
182 | sem_set( pbuffer->semid, pbuffer->blocks_free_lock, blocks - 1 ); | |
183 | +#else | |
184 | + sem_set( pbuffer->semid, pbuffer->blocks_free_lock, blocks ); | |
185 | +#endif | |
186 | ||
187 | /* Detattach the shared memory so the fork doesnt do anything odd */ | |
188 | shmdt( (char *)pbuffer ); | |
189 | @@ -648,7 +679,7 @@ | |
190 | int | |
191 | fill_block() | |
192 | { | |
193 | - int bytes; | |
194 | + int bytes = 0; | |
195 | char *start; | |
196 | int toread; | |
197 | static char eof_reached = 0; | |
198 | @@ -707,7 +738,7 @@ | |
199 | { | |
200 | int filled = 0; | |
201 | int maxfilled = (blocks * percent) / 100; | |
202 | - int first_block; | |
203 | + int first_block = 0; | |
204 | ||
205 | if( debug ) | |
206 | fprintf( stderr, "\tW: Entering writer\n blocks = %d\n maxfilled = %d\n", | |
207 | @@ -742,7 +773,7 @@ | |
208 | } | |
209 | ||
210 | if( print_total ){ | |
211 | - fprintf( stderr, "Kilobytes Out %lu\n", outk ); | |
212 | + fprintf( stderr, "Kilobytes Out %" NUM_K_FMT "\n", outk ); | |
213 | } | |
214 | ||
215 | if( debug ) | |
216 | @@ -783,14 +814,14 @@ | |
217 | void | |
218 | write_block_to_stdout() | |
219 | { | |
220 | - static unsigned long out = 0; | |
221 | + unsigned long out = 0; | |
222 | static unsigned long last_gb = 0; | |
223 | - static unsigned long next_k = 0; | |
224 | + static NUM_K_TYPE next_k = 0; | |
225 | int written; | |
226 | ||
227 | if( next_k == 0 && showevery ){ | |
228 | if( debug > 3 ) | |
229 | - fprintf( stderr, "W: next_k = %lu showevery = %d\n", next_k, showevery ); | |
230 | + fprintf( stderr, "W: next_k = %" NUM_K_FMT " showevery = %d\n", next_k, showevery ); | |
231 | showevery = showevery / 1024; | |
232 | next_k = showevery; | |
233 | } | |
234 | @@ -798,7 +829,7 @@ | |
235 | if( (written = write( fdout, curr_block->data, curr_block->bytes )) != curr_block->bytes ){ | |
236 | report_proc(); | |
237 | perror( "write of data failed" ); | |
238 | - fprintf( stderr, "bytes to write=%d, bytes written=%d, total written %10luK\n", curr_block->bytes, written, outk ); | |
239 | + fprintf( stderr, "bytes to write=%d, bytes written=%d, total written %10" NUM_K_FMT "K\n", curr_block->bytes, written, outk ); | |
240 | byee( -1 ); | |
241 | } | |
242 | ||
243 | @@ -825,7 +856,7 @@ | |
244 | } | |
245 | if( showevery ){ | |
246 | if( debug > 3 ) | |
247 | - fprintf( stderr, "W: outk = %lu, next_k = %lu\n", | |
248 | + fprintf( stderr, "W: outk = %" NUM_K_FMT ", next_k = %" NUM_K_FMT "\n", | |
249 | outk, next_k ); | |
250 | if( outk >= next_k ){ | |
251 | pr_out(); | |
252 | @@ -914,13 +945,12 @@ | |
253 | do_size( arg ) | |
254 | char *arg; | |
255 | { | |
256 | - char format[ 20 ]; | |
257 | - int ret; | |
258 | + int ret = 0; | |
259 | ||
260 | - *format = '\0'; | |
261 | - sscanf( arg, "%d%s", &ret, format ); | |
262 | + char unit = '\0'; | |
263 | + sscanf( arg, "%d%c", &ret, &unit ); | |
264 | ||
265 | - switch( *format ){ | |
266 | + switch( unit ){ | |
267 | case 'm': | |
268 | case 'M': | |
269 | ret = ret K K; | |
270 | @@ -941,7 +971,36 @@ | |
271 | void | |
272 | pr_out() | |
273 | { | |
274 | - fprintf( stderr, " %10luK\r", outk ); | |
275 | + struct timeval now; | |
276 | + unsigned long ms_delta, k_per_s; | |
277 | + | |
278 | + gettimeofday(&now, NULL); | |
279 | + ms_delta = (now.tv_sec - starttime.tv_sec) * 1000 | |
280 | + + (now.tv_usec - starttime.tv_usec) / 1000; | |
281 | + if (ms_delta) { | |
282 | + /* Use increased accuracy for small amounts of data, | |
283 | + * decreased accuracy for *huge* throughputs > 4.1GB/s | |
284 | + * to avoid division by 0. This will overflow if your | |
285 | + * machine's throughput exceeds 4TB/s - you deserve to | |
286 | + * loose if you're still using 32 bit longs on such a | |
287 | + * beast ;-) | |
288 | + * <mbuck@debian.org> | |
289 | + */ | |
290 | + if (outk < ULONG_MAX / 1000) { | |
291 | + k_per_s = (outk * 1000) / ms_delta; | |
292 | + } else if (ms_delta >= 1000) { | |
293 | + k_per_s = outk / (ms_delta / 1000); | |
294 | + } else { | |
295 | + k_per_s = (outk / ms_delta) * 1000; | |
296 | + } | |
297 | + fprintf( stderr, " %10" NUM_K_FMT "K, %10luK/s\r", outk, k_per_s ); | |
298 | + } else { | |
299 | + if (outk) { | |
300 | + fprintf( stderr, " %10" NUM_K_FMT "K, ?K/s\r", outk ); | |
301 | + } else { | |
302 | + fprintf( stderr, " 0K, 0K/s\r"); | |
303 | + } | |
304 | + } | |
305 | } | |
306 | ||
307 | #ifdef SYS5 | |
308 | --- buffer-1.19.orig/sem.c | |
309 | +++ buffer-1.19/sem.c | |
310 | @@ -27,6 +27,7 @@ | |
311 | * semaphores */ | |
312 | ||
313 | #include <stdio.h> | |
314 | +#include <unistd.h> | |
315 | #include <sys/types.h> | |
316 | #include <sys/stat.h> | |
317 | #include <sys/ipc.h> | |
318 | @@ -34,6 +35,20 @@ | |
319 | #include <errno.h> | |
320 | #include "sem.h" | |
321 | ||
322 | +/* If we've got a version of glibc that doesn't define union semun, we do | |
323 | + * it ourseleves like in semctl(2). Otherwise, fall back to the original | |
324 | + * buffer behaviour of defining it (differetly!) only on some systems. | |
325 | + * | |
326 | + * mbuck@debian.org, 1999/08/29 | |
327 | + */ | |
328 | +#if defined(__GNU_LIBRARY__) && defined(_SEM_SEMUN_UNDEFINED) | |
329 | +union semun { | |
330 | + int val; /* value for SETVAL */ | |
331 | + struct semid_ds *buf; /* buffer for IPC_STAT & IPC_SET */ | |
332 | + unsigned short int *array; /* array for GETALL & SETALL */ | |
333 | + struct seminfo *__buf; /* buffer for IPC_INFO */ | |
334 | +}; | |
335 | +#else | |
336 | #if defined(SYS5) || defined(ultrix) || defined(_AIX) | |
337 | union semun { | |
338 | int val; | |
339 | @@ -41,6 +56,7 @@ | |
340 | ushort *array; | |
341 | }; | |
342 | #endif | |
343 | +#endif | |
344 | ||
345 | /* IMPORTS */ | |
346 | ||
347 | @@ -95,7 +111,7 @@ | |
348 | return sem; | |
349 | } | |
350 | ||
351 | -static | |
352 | +static void | |
353 | do_sem( sem_id, pbuf, err ) | |
354 | int sem_id; | |
355 | struct sembuf *pbuf; | |
356 | @@ -149,10 +165,13 @@ | |
357 | remove_sems( sem_id ) | |
358 | int sem_id; | |
359 | { | |
360 | + union semun arg; | |
361 | + | |
362 | if( sem_id == -1 ) | |
363 | return; | |
364 | ||
365 | - if( semctl( sem_id, 0, IPC_RMID, NULL ) == -1 ){ | |
366 | + arg.val = 0; | |
367 | + if( semctl( sem_id, 0, IPC_RMID, arg ) == -1 ){ | |
368 | report_proc(); | |
369 | perror( "internal error, failed to remove semaphore" ); | |
370 | } |