log.c 2.9 KB

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