syslog.c 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. #include <u.h>
  2. #include <libc.h>
  3. static struct
  4. {
  5. int fd;
  6. int consfd;
  7. char *name;
  8. Dir *d;
  9. Dir *consd;
  10. Lock;
  11. } sl =
  12. {
  13. -1, -1,
  14. };
  15. static void
  16. _syslogopen(void)
  17. {
  18. char buf[1024];
  19. if(sl.fd >= 0)
  20. close(sl.fd);
  21. snprint(buf, sizeof(buf), "/sys/log/%s", sl.name);
  22. sl.fd = open(buf, OWRITE|OCEXEC);
  23. }
  24. static int
  25. eqdirdev(Dir *a, Dir *b)
  26. {
  27. return a != nil && b != nil &&
  28. a->dev == b->dev && a->type == b->type &&
  29. a->qid.path == b->qid.path;
  30. }
  31. /*
  32. * Print
  33. * sysname: time: mesg
  34. * on /sys/log/logname.
  35. * If cons or log file can't be opened, print on the system console, too.
  36. */
  37. void
  38. syslog(int cons, char *logname, char *fmt, ...)
  39. {
  40. char buf[1024];
  41. char *ctim, *p;
  42. va_list arg;
  43. int n;
  44. Dir *d;
  45. char err[ERRMAX];
  46. err[0] = '\0';
  47. errstr(err, sizeof err);
  48. lock(&sl);
  49. /*
  50. * paranoia makes us stat to make sure a fork+close
  51. * hasn't broken our fd's
  52. */
  53. d = dirfstat(sl.fd);
  54. if(sl.fd < 0 || sl.name == nil || strcmp(sl.name, logname) != 0 ||
  55. !eqdirdev(d, sl.d)){
  56. free(sl.name);
  57. sl.name = strdup(logname);
  58. if(sl.name == nil)
  59. cons = 1;
  60. else{
  61. free(sl.d);
  62. sl.d = nil;
  63. _syslogopen();
  64. if(sl.fd < 0)
  65. cons = 1;
  66. else
  67. sl.d = dirfstat(sl.fd);
  68. }
  69. }
  70. free(d);
  71. if(cons){
  72. d = dirfstat(sl.consfd);
  73. if(sl.consfd < 0 || !eqdirdev(d, sl.consd)){
  74. free(sl.consd);
  75. sl.consd = nil;
  76. sl.consfd = open("#c/cons", OWRITE|OCEXEC);
  77. if(sl.consfd >= 0)
  78. sl.consd = dirfstat(sl.consfd);
  79. }
  80. free(d);
  81. }
  82. if(fmt == nil){
  83. unlock(&sl);
  84. return;
  85. }
  86. ctim = ctime(time(0));
  87. werrstr(err);
  88. p = buf + snprint(buf, sizeof(buf)-1, "%s ", sysname());
  89. strncpy(p, ctim+4, 15);
  90. p += 15;
  91. *p++ = ' ';
  92. va_start(arg, fmt);
  93. p = vseprint(p, buf+sizeof(buf)-1, fmt, arg);
  94. va_end(arg);
  95. *p++ = '\n';
  96. n = p - buf;
  97. if(sl.fd >= 0){
  98. seek(sl.fd, 0, 2);
  99. write(sl.fd, buf, n);
  100. }
  101. if(cons && sl.consfd >=0)
  102. write(sl.consfd, buf, n);
  103. unlock(&sl);
  104. }