Print this page
10120 smatch indenting fixes for usr/src/cmd
Reviewed by: Gergő Doma <domag02@gmail.com>
Portions contributed by: Joyce McIntosh <joyce.mcintosh@nexenta.com>
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/cat/cat.c
+++ new/usr/src/cmd/cat/cat.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
↓ open down ↓ |
19 lines elided |
↑ open up ↑ |
20 20 */
21 21 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
22 22 /* All Rights Reserved */
23 23
24 24
25 25 /*
26 26 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
27 27 * Use is subject to license terms.
28 28 */
29 29
30 +/*
31 + * Copyright (c) 2018, Joyent, Inc.
32 + */
30 33
31 34 /*
32 35 * Concatenate files.
33 36 */
34 37
35 38 #include <stdio.h>
36 39 #include <stdlib.h>
37 40 #include <ctype.h>
38 41 #include <sys/types.h>
39 42 #include <sys/stat.h>
40 43 #include <locale.h>
41 44 #include <unistd.h>
42 45 #include <sys/mman.h>
43 46 #include <errno.h>
44 47 #include <string.h>
45 48
46 49 #include <widec.h>
47 50 #include <wctype.h>
48 51 #include <limits.h>
49 52 #include <libintl.h>
50 53 #define IDENTICAL(A, B) (A.st_dev == B.st_dev && A.st_ino == B.st_ino)
51 54
52 55 #define MAXMAPSIZE (8*1024*1024) /* map at most 8MB */
53 56 #define SMALLFILESIZE (32*1024) /* don't use mmap on little files */
54 57
55 58 static int vncat(FILE *);
56 59 static int cat(FILE *, struct stat *, struct stat *, char *);
57 60
58 61 static int silent = 0; /* s flag */
59 62 static int visi_mode = 0; /* v flag */
60 63 static int visi_tab = 0; /* t flag */
61 64 static int visi_newline = 0; /* e flag */
62 65 static int bflg = 0; /* b flag */
63 66 static int nflg = 0; /* n flag */
64 67 static long ibsize;
65 68 static long obsize;
66 69 static unsigned char buf[SMALLFILESIZE];
67 70
68 71
69 72 int
70 73 main(int argc, char **argv)
71 74 {
72 75 FILE *fi;
73 76 int c;
74 77 extern int optind;
75 78 int errflg = 0;
76 79 int stdinflg = 0;
77 80 int status = 0;
78 81 int estatus = 0;
79 82 struct stat source, target;
80 83
81 84 (void) setlocale(LC_ALL, "");
82 85 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
83 86 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */
84 87 #endif
85 88 (void) textdomain(TEXT_DOMAIN);
86 89
87 90 #ifdef STANDALONE
88 91 /*
89 92 * If the first argument is NULL,
90 93 * discard arguments until we find cat.
91 94 */
92 95 if (argv[0][0] == '\0')
93 96 argc = getargv("cat", &argv, 0);
94 97 #endif
95 98
96 99 /*
97 100 * Process the options for cat.
98 101 */
99 102
100 103 while ((c = getopt(argc, argv, "usvtebn")) != EOF) {
101 104 switch (c) {
102 105
103 106 case 'u':
104 107
105 108 /*
106 109 * If not standalone, set stdout to
107 110 * completely unbuffered I/O when
108 111 * the 'u' option is used.
109 112 */
110 113
111 114 #ifndef STANDALONE
112 115 setbuf(stdout, (char *)NULL);
113 116 #endif
114 117 continue;
115 118
116 119 case 's':
117 120
118 121 /*
119 122 * The 's' option requests silent mode
120 123 * where no messages are written.
121 124 */
122 125
123 126 silent++;
124 127 continue;
125 128
126 129 case 'v':
127 130
128 131 /*
129 132 * The 'v' option requests that non-printing
130 133 * characters (with the exception of newlines,
131 134 * form-feeds, and tabs) be displayed visibly.
132 135 *
133 136 * Control characters are printed as "^x".
134 137 * DEL characters are printed as "^?".
135 138 * Non-printable and non-contrlol characters with the
136 139 * 8th bit set are printed as "M-x".
137 140 */
138 141
139 142 visi_mode++;
140 143 continue;
141 144
142 145 case 't':
143 146
144 147 /*
145 148 * When in visi_mode, this option causes tabs
146 149 * to be displayed as "^I".
147 150 */
148 151
149 152 visi_tab++;
150 153 continue;
151 154
152 155 case 'e':
153 156
154 157 /*
155 158 * When in visi_mode, this option causes newlines
156 159 * and form-feeds to be displayed as "$" at the end
157 160 * of the line prior to the newline.
158 161 */
159 162
160 163 visi_newline++;
161 164 continue;
162 165
163 166 case 'b':
164 167
165 168 /*
166 169 * Precede each line output with its line number,
167 170 * but omit the line numbers from blank lines.
168 171 */
169 172
170 173 bflg++;
171 174 nflg++;
172 175 continue;
173 176
174 177 case 'n':
175 178
176 179 /*
177 180 * Precede each line output with its line number.
178 181 */
179 182
180 183 nflg++;
181 184 continue;
182 185
183 186 case '?':
184 187 errflg++;
185 188 break;
186 189 }
187 190 break;
188 191 }
189 192
190 193 if (errflg) {
191 194 if (!silent)
192 195 (void) fprintf(stderr,
193 196 gettext("usage: cat [ -usvtebn ] [-|file] ...\n"));
194 197 exit(2);
195 198 }
196 199
197 200 /*
198 201 * Stat stdout to be sure it is defined.
199 202 */
200 203
201 204 if (fstat(fileno(stdout), &target) < 0) {
202 205 if (!silent)
203 206 (void) fprintf(stderr,
204 207 gettext("cat: Cannot stat stdout\n"));
205 208 exit(2);
206 209 }
207 210 obsize = target.st_blksize;
208 211
209 212 /*
210 213 * If no arguments given, then use stdin for input.
211 214 */
212 215
213 216 if (optind == argc) {
214 217 argc++;
215 218 stdinflg++;
216 219 }
217 220
218 221 /*
219 222 * Process each remaining argument,
220 223 * unless there is an error with stdout.
221 224 */
222 225
223 226
224 227 for (argv = &argv[optind];
225 228 optind < argc && !ferror(stdout); optind++, argv++) {
226 229
227 230 /*
228 231 * If the argument was '-' or there were no files
229 232 * specified, take the input from stdin.
230 233 */
231 234
232 235 if (stdinflg ||
233 236 ((*argv)[0] == '-' && (*argv)[1] == '\0'))
234 237 fi = stdin;
235 238 else {
236 239 /*
237 240 * Attempt to open each specified file.
238 241 */
239 242
240 243 if ((fi = fopen(*argv, "r")) == NULL) {
241 244 if (!silent)
242 245 (void) fprintf(stderr, gettext(
243 246 "cat: cannot open %s: %s\n"),
244 247 *argv, strerror(errno));
245 248 status = 2;
246 249 continue;
247 250 }
248 251 }
249 252
250 253 /*
251 254 * Stat source to make sure it is defined.
252 255 */
253 256
254 257 if (fstat(fileno(fi), &source) < 0) {
255 258 if (!silent)
256 259 (void) fprintf(stderr,
257 260 gettext("cat: cannot stat %s: %s\n"),
258 261 (stdinflg) ? "-" : *argv, strerror(errno));
259 262 status = 2;
260 263 continue;
261 264 }
262 265
263 266
↓ open down ↓ |
224 lines elided |
↑ open up ↑ |
264 267 /*
265 268 * If the source is not a character special file, socket or a
266 269 * block special file, make sure it is not identical
267 270 * to the target.
268 271 */
269 272
270 273 if (!S_ISCHR(target.st_mode) &&
271 274 !S_ISBLK(target.st_mode) &&
272 275 !S_ISSOCK(target.st_mode) &&
273 276 IDENTICAL(target, source)) {
274 - if (!silent)
275 - (void) fprintf(stderr,
276 - gettext("cat: input/output files '%s' identical\n"),
277 - stdinflg?"-": *argv);
277 + if (!silent) {
278 + (void) fprintf(stderr, gettext("cat: "
279 + "input/output files '%s' identical\n"),
280 + stdinflg?"-": *argv);
281 + }
282 +
278 283 if (fclose(fi) != 0)
279 284 (void) fprintf(stderr,
280 285 gettext("cat: close error: %s\n"),
281 286 strerror(errno));
282 287 status = 2;
283 288 continue;
284 289 }
285 290 ibsize = source.st_blksize;
286 291
287 292 /*
288 293 * If in visible mode and/or nflg, use vncat;
289 294 * otherwise, use cat.
290 295 */
291 296
292 297 if (visi_mode || nflg)
293 298 estatus = vncat(fi);
294 299 else
295 300 estatus = cat(fi, &source, &target,
296 301 fi != stdin ? *argv : "standard input");
297 302
298 303 if (estatus)
299 304 status = estatus;
300 305
301 306 /*
302 307 * If the input is not stdin, close the source file.
303 308 */
304 309
305 310 if (fi != stdin) {
306 311 if (fclose(fi) != 0)
307 312 if (!silent)
308 313 (void) fprintf(stderr,
309 314 gettext("cat: close error: %s\n"),
310 315 strerror(errno));
311 316 }
312 317 }
313 318
314 319 /*
315 320 * Display any error with stdout operations.
316 321 */
317 322
318 323 if (fclose(stdout) != 0) {
319 324 if (!silent)
320 325 perror(gettext("cat: close error"));
321 326 status = 2;
322 327 }
323 328 return (status);
324 329 }
325 330
326 331
327 332
328 333 static int
329 334 cat(FILE *fi, struct stat *statp, struct stat *outp, char *filenm)
330 335 {
331 336 int nitems;
332 337 int nwritten;
333 338 int offset;
334 339 int fi_desc;
335 340 long buffsize;
336 341 char *bufferp;
337 342 off_t mapsize, munmapsize;
338 343 off_t filesize;
339 344 off_t mapoffset;
340 345
341 346 fi_desc = fileno(fi);
342 347 if (S_ISREG(statp->st_mode) && (lseek(fi_desc, (off_t)0, SEEK_CUR)
343 348 == 0) && (statp->st_size > SMALLFILESIZE)) {
344 349 mapsize = (off_t)MAXMAPSIZE;
345 350 if (statp->st_size < mapsize)
346 351 mapsize = statp->st_size;
347 352 munmapsize = mapsize;
348 353
349 354 /*
350 355 * Mmap time!
351 356 */
352 357 bufferp = mmap((caddr_t)NULL, (size_t)mapsize, PROT_READ,
353 358 MAP_SHARED, fi_desc, (off_t)0);
354 359 if (bufferp == (caddr_t)-1)
355 360 mapsize = 0; /* I guess we can't mmap today */
356 361 } else
357 362 mapsize = 0; /* can't mmap non-regular files */
358 363
359 364 if (mapsize != 0) {
360 365 int read_error = 0;
361 366 char x;
362 367
363 368 /*
364 369 * NFS V2 will let root open a file it does not have permission
365 370 * to read. This read() is here to make sure that the access
366 371 * time on the input file will be updated. The VSC tests for
367 372 * cat do this:
368 373 * cat file > /dev/null
369 374 * In this case the write()/mmap() pair will not read the file
370 375 * and the access time will not be updated.
371 376 */
372 377
373 378 if (read(fi_desc, &x, 1) == -1)
374 379 read_error = 1;
375 380 mapoffset = 0;
376 381 filesize = statp->st_size;
377 382 for (;;) {
378 383 /*
379 384 * Note that on some systems (V7), very large writes to
380 385 * a pipe return less than the requested size of the
381 386 * write. In this case, multiple writes are required.
382 387 */
383 388 offset = 0;
384 389 nitems = (int)mapsize;
385 390 do {
386 391 if ((nwritten = write(fileno(stdout),
387 392 &bufferp[offset], (size_t)nitems)) < 0) {
388 393 if (!silent) {
389 394 if (read_error == 1)
390 395 (void) fprintf(
391 396 stderr, gettext(
392 397 "cat: cannot read "
393 398 "%s: "), filenm);
394 399 else
395 400 (void) fprintf(stderr,
396 401 gettext(
397 402 "cat: write "
398 403 "error: "));
399 404 perror("");
400 405 }
401 406 (void) munmap(bufferp,
402 407 (size_t)munmapsize);
403 408 (void) lseek(fi_desc, (off_t)mapoffset,
404 409 SEEK_SET);
405 410 return (2);
406 411 }
407 412 offset += nwritten;
408 413 } while ((nitems -= nwritten) > 0);
409 414
410 415 filesize -= mapsize;
411 416 mapoffset += mapsize;
412 417 if (filesize == 0)
413 418 break;
414 419 if (filesize < mapsize)
415 420 mapsize = filesize;
416 421 if (mmap(bufferp, (size_t)mapsize, PROT_READ,
417 422 MAP_SHARED|MAP_FIXED, fi_desc,
418 423 mapoffset) == (caddr_t)-1) {
419 424 if (!silent)
420 425 perror(gettext("cat: mmap error"));
421 426 (void) munmap(bufferp, (size_t)munmapsize);
422 427 (void) lseek(fi_desc, (off_t)mapoffset,
423 428 SEEK_SET);
424 429 return (1);
425 430 }
426 431 }
427 432 /*
428 433 * Move the file pointer past what we read. Shell scripts
429 434 * rely on cat to do this, so that successive commands in
430 435 * the script won't re-read the same data.
431 436 */
432 437 (void) lseek(fi_desc, (off_t)mapoffset, SEEK_SET);
433 438 (void) munmap(bufferp, (size_t)munmapsize);
434 439 } else {
435 440 if (S_ISREG(statp->st_mode) && S_ISREG(outp->st_mode)) {
436 441 bufferp = (char *)buf;
437 442 buffsize = SMALLFILESIZE;
438 443 } else {
439 444 if (obsize)
440 445 /*
441 446 * common case, use output blksize
442 447 */
443 448 buffsize = obsize;
444 449 else if (ibsize)
445 450 buffsize = ibsize;
446 451 else
447 452 buffsize = (long)BUFSIZ;
448 453
449 454 if (buffsize <= SMALLFILESIZE) {
450 455 bufferp = (char *)buf;
451 456 } else if ((bufferp =
452 457 malloc((size_t)buffsize)) == NULL) {
453 458 perror(gettext("cat: no memory"));
454 459 return (1);
455 460 }
456 461 }
457 462
458 463 /*
459 464 * While not end of file, copy blocks to stdout.
460 465 */
461 466 while ((nitems = read(fi_desc, bufferp, (size_t)buffsize)) >
462 467 0) {
463 468 offset = 0;
464 469 /*
465 470 * Note that on some systems (V7), very large writes
466 471 * to a pipe return less than the requested size of
467 472 * the write. In this case, multiple writes are
468 473 * required.
469 474 */
470 475 do {
471 476 nwritten = write(1, bufferp+offset,
472 477 (size_t)nitems);
473 478 if (nwritten < 0) {
474 479 if (!silent) {
475 480 if (nwritten == -1)
476 481 nwritten = 0l;
477 482 (void) fprintf(stderr, gettext(\
478 483 "cat: output error (%d/%d characters written)\n"), nwritten, nitems);
479 484 perror("");
480 485 }
481 486 if (bufferp != (char *)buf)
482 487 free(bufferp);
483 488 return (2);
484 489 }
485 490 offset += nwritten;
486 491 } while ((nitems -= nwritten) > 0);
487 492 }
488 493 if (bufferp != (char *)buf)
489 494 free(bufferp);
490 495 if (nitems < 0) {
491 496 (void) fprintf(stderr,
492 497 gettext("cat: input error on %s: "), filenm);
493 498 perror("");
494 499 return (1);
495 500 }
496 501 }
497 502
498 503 return (0);
499 504 }
500 505
501 506 static int
502 507 vncat(fi)
503 508 FILE *fi;
504 509 {
505 510 int c;
506 511 int lno;
507 512 int boln; /* = 1 if at beginning of line */
508 513 /* = 0 otherwise */
509 514 wchar_t wc;
510 515 int len, n;
511 516 unsigned char *p1, *p2;
512 517
513 518 lno = 1;
514 519 boln = 1;
515 520 p1 = p2 = buf;
516 521 for (;;) {
517 522 if (p1 >= p2) {
518 523 p1 = buf;
519 524 if ((len = fread(p1, 1, BUFSIZ, fi)) <= 0)
520 525 break;
521 526 p2 = p1 + len;
522 527 }
523 528 c = *p1++;
524 529
525 530 /*
526 531 * Display newlines as "$<newline>"
527 532 * if visi_newline set
528 533 */
529 534 if (c == '\n') {
530 535 if (nflg && boln && !bflg)
531 536 (void) printf("%6d\t", lno++);
532 537 boln = 1;
533 538
534 539 if (visi_mode && visi_newline)
535 540 (void) putchar('$');
536 541 (void) putchar(c);
537 542 continue;
538 543 }
539 544
540 545 if (nflg && boln)
541 546 (void) printf("%6d\t", lno++);
542 547 boln = 0;
543 548
544 549 /*
545 550 * For non-printable and non-cntrl chars,
546 551 * use the "M-x" notation.
547 552 */
548 553
549 554 if (isascii(c)) {
550 555 if (isprint(c) || visi_mode == 0) {
551 556 (void) putchar(c);
552 557 continue;
553 558 }
554 559
555 560 /*
556 561 * For non-printable ascii characters.
557 562 */
558 563
559 564 if (iscntrl(c)) {
560 565 /* For cntrl characters. */
561 566 if ((c == '\t') || (c == '\f')) {
562 567 /*
563 568 * Display tab as "^I" if visi_tab set
564 569 */
565 570 if (visi_mode && visi_tab) {
566 571 (void) putchar('^');
567 572 (void) putchar(c^0100);
568 573 } else
569 574 (void) putchar(c);
570 575 continue;
571 576 }
572 577 (void) putchar('^');
573 578 (void) putchar(c^0100);
574 579 continue;
575 580 }
576 581 continue;
577 582 }
578 583
579 584 /*
580 585 * For non-ascii characters.
581 586 */
582 587 p1--;
583 588 if ((len = (p2 - p1)) < MB_LEN_MAX) {
584 589 for (n = 0; n < len; n++)
585 590 buf[n] = *p1++;
586 591 p1 = buf;
587 592 p2 = p1 + n;
588 593 if ((len = fread(p2, 1, BUFSIZ - n, fi)) > 0)
589 594 p2 += len;
590 595 }
591 596
592 597 if ((len = (p2 - p1)) > MB_LEN_MAX)
593 598 len = MB_LEN_MAX;
594 599
595 600 if ((len = mbtowc(&wc, (char *)p1, len)) > 0) {
596 601 if (iswprint(wc) || visi_mode == 0) {
597 602 (void) putwchar(wc);
598 603 p1 += len;
599 604 continue;
600 605 }
601 606 }
602 607
603 608 (void) putchar('M');
604 609 (void) putchar('-');
605 610 c -= 0200;
606 611
607 612 if (isprint(c)) {
608 613 (void) putchar(c);
609 614 }
610 615
611 616 /* For non-printable characters. */
612 617 if (iscntrl(c)) {
613 618 /* For cntrl characters. */
614 619 if ((c == '\t') || (c == '\f')) {
615 620 /*
616 621 * Display tab as "^I" if visi_tab set
617 622 */
618 623 if (visi_mode && visi_tab) {
619 624 (void) putchar('^');
620 625 (void) putchar(c^0100);
621 626 } else
622 627 (void) putchar(c);
623 628 } else {
624 629 (void) putchar('^');
625 630 (void) putchar(c^0100);
626 631 }
627 632 }
628 633 p1++;
629 634 }
630 635 return (0);
631 636 }
↓ open down ↓ |
344 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX