log.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. #include "u.h"
  2. #include "../port/lib.h"
  3. #include "mem.h"
  4. #include "dat.h"
  5. #include "fns.h"
  6. #include "../port/error.h"
  7. static char Ebadlogctl[] = "unknown log ctl message";
  8. void
  9. logopen(Log *alog)
  10. {
  11. lock(alog);
  12. if(waserror()){
  13. unlock(alog);
  14. nexterror();
  15. }
  16. if(alog->opens == 0){
  17. if(alog->nlog == 0)
  18. alog->nlog = 4*1024;
  19. if(alog->minread == 0)
  20. alog->minread = 1;
  21. if(alog->buf == nil)
  22. alog->buf = malloc(alog->nlog);
  23. alog->rptr = alog->buf;
  24. alog->end = alog->buf + alog->nlog;
  25. alog->len = 0;
  26. }
  27. alog->opens++;
  28. unlock(alog);
  29. poperror();
  30. }
  31. void
  32. logclose(Log *alog)
  33. {
  34. lock(alog);
  35. alog->opens--;
  36. if(alog->opens == 0){
  37. free(alog->buf);
  38. alog->buf = nil;
  39. }
  40. unlock(alog);
  41. }
  42. static int
  43. logready(void *a)
  44. {
  45. Log *alog = a;
  46. return alog->len >= alog->minread;
  47. }
  48. long
  49. logread(Log *alog, void *a, ulong, long n)
  50. {
  51. int i, d;
  52. char *p, *rptr;
  53. qlock(&alog->readq);
  54. if(waserror()){
  55. qunlock(&alog->readq);
  56. nexterror();
  57. }
  58. for(;;){
  59. lock(alog);
  60. if(alog->len >= alog->minread || alog->len >= n){
  61. if(n > alog->len)
  62. n = alog->len;
  63. d = 0;
  64. rptr = alog->rptr;
  65. alog->rptr += n;
  66. if(alog->rptr >= alog->end){
  67. d = alog->rptr - alog->end;
  68. alog->rptr = alog->buf + d;
  69. }
  70. alog->len -= n;
  71. unlock(alog);
  72. i = n-d;
  73. p = a;
  74. memmove(p, rptr, i);
  75. memmove(p+i, alog->buf, d);
  76. break;
  77. }
  78. else
  79. unlock(alog);
  80. sleep(&alog->readr, logready, alog);
  81. }
  82. qunlock(&alog->readq);
  83. poperror();
  84. return n;
  85. }
  86. char*
  87. logctl(Log *alog, int argc, char *argv[], Logflag *flags)
  88. {
  89. int i, set;
  90. Logflag *fp;
  91. if(argc < 2)
  92. return Ebadlogctl;
  93. if(strcmp("set", argv[0]) == 0)
  94. set = 1;
  95. else if(strcmp("clear", argv[0]) == 0)
  96. set = 0;
  97. else
  98. return Ebadlogctl;
  99. for(i = 1; i < argc; i++){
  100. for(fp = flags; fp->name; fp++)
  101. if(strcmp(fp->name, argv[i]) == 0)
  102. break;
  103. if(fp->name == nil)
  104. continue;
  105. if(set)
  106. alog->logmask |= fp->mask;
  107. else
  108. alog->logmask &= ~fp->mask;
  109. }
  110. return nil;
  111. }
  112. void
  113. logn(Log *alog, int mask, void *buf, int n)
  114. {
  115. char *fp, *t;
  116. int dowake, i;
  117. if(!(alog->logmask & mask))
  118. return;
  119. if(alog->opens == 0)
  120. return;
  121. if(n > alog->nlog)
  122. return;
  123. lock(alog);
  124. i = alog->len + n - alog->nlog;
  125. if(i > 0){
  126. alog->len -= i;
  127. alog->rptr += i;
  128. if(alog->rptr >= alog->end)
  129. alog->rptr = alog->buf + (alog->rptr - alog->end);
  130. }
  131. t = alog->rptr + alog->len;
  132. fp = buf;
  133. alog->len += n;
  134. while(n-- > 0){
  135. if(t >= alog->end)
  136. t = alog->buf + (t - alog->end);
  137. *t++ = *fp++;
  138. }
  139. dowake = alog->len >= alog->minread;
  140. unlock(alog);
  141. if(dowake)
  142. wakeup(&alog->readr);
  143. }
  144. void
  145. log(Log *alog, int mask, char *fmt, ...)
  146. {
  147. int n;
  148. va_list arg;
  149. char buf[128];
  150. if(!(alog->logmask & mask))
  151. return;
  152. if(alog->opens == 0)
  153. return;
  154. va_start(arg, fmt);
  155. n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf;
  156. va_end(arg);
  157. logn(alog, mask, buf, n);
  158. }