read.c 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include <u.h>
  10. #include <libc.h>
  11. int multi;
  12. int nlines;
  13. char *status = nil;
  14. int
  15. line(int fd, char *file)
  16. {
  17. char c;
  18. int m, n, nalloc;
  19. char *buf;
  20. nalloc = 0;
  21. buf = nil;
  22. for(m=0; ; ){
  23. n = read(fd, &c, 1);
  24. if(n < 0){
  25. fprint(2, "read: error reading %s: %r\n", file);
  26. exits("read error");
  27. }
  28. if(n == 0){
  29. if(m == 0)
  30. status = "eof";
  31. break;
  32. }
  33. if(m == nalloc){
  34. nalloc += 1024;
  35. buf = realloc(buf, nalloc);
  36. if(buf == nil){
  37. fprint(2, "read: malloc error: %r\n");
  38. exits("malloc");
  39. }
  40. }
  41. buf[m++] = c;
  42. if(c == '\n')
  43. break;
  44. }
  45. if(m > 0)
  46. write(1, buf, m);
  47. free(buf);
  48. return m;
  49. }
  50. void
  51. lines(int fd, char *file)
  52. {
  53. do{
  54. if(line(fd, file) == 0)
  55. break;
  56. }while(multi || --nlines>0);
  57. }
  58. void
  59. main(int argc, char *argv[])
  60. {
  61. int i, fd;
  62. char *s;
  63. ARGBEGIN{
  64. case 'm':
  65. multi = 1;
  66. break;
  67. case 'n':
  68. s = ARGF();
  69. if(s){
  70. nlines = atoi(s);
  71. break;
  72. }
  73. /* fall through */
  74. default:
  75. fprint(2, "usage: read [-m] [-n nlines] [files...]\n");
  76. exits("usage");
  77. }ARGEND
  78. if(argc == 0)
  79. lines(0, "<stdin>");
  80. else
  81. for(i=0; i<argc; i++){
  82. fd = open(argv[i], OREAD);
  83. if(fd < 0){
  84. fprint(2, "read: can't open %s: %r\n", argv[i]);
  85. exits("open");
  86. }
  87. lines(fd, argv[i]);
  88. close(fd);
  89. }
  90. exits(status);
  91. }