osdep-openbsd.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /* $OpenBSD$ */
  2. /*
  3. * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
  4. *
  5. * Permission to use, copy, modify, and distribute this software for any
  6. * purpose with or without fee is hereby granted, provided that the above
  7. * copyright notice and this permission notice appear in all copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  10. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  11. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  12. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  13. * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
  14. * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
  15. * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  16. */
  17. #include <sys/param.h> /* MAXCOMLEN */
  18. #include <sys/types.h>
  19. #include <sys/proc.h>
  20. #include <sys/sysctl.h>
  21. #include <sys/stat.h>
  22. #include <errno.h>
  23. #include <event.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #include <unistd.h>
  27. #ifndef nitems
  28. #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
  29. #endif
  30. #define is_runnable(p) \
  31. ((p)->p_stat == SRUN || (p)->p_stat == SIDL || (p)->p_stat == SONPROC)
  32. #define is_stopped(p) \
  33. ((p)->p_stat == SSTOP || (p)->p_stat == SDEAD)
  34. struct kinfo_proc *cmp_procs(struct kinfo_proc *, struct kinfo_proc *);
  35. char *osdep_get_name(int, char *);
  36. char *osdep_get_cwd(int);
  37. struct event_base *osdep_event_init(void);
  38. struct kinfo_proc *
  39. cmp_procs(struct kinfo_proc *p1, struct kinfo_proc *p2)
  40. {
  41. if (is_runnable(p1) && !is_runnable(p2))
  42. return (p1);
  43. if (!is_runnable(p1) && is_runnable(p2))
  44. return (p2);
  45. if (is_stopped(p1) && !is_stopped(p2))
  46. return (p1);
  47. if (!is_stopped(p1) && is_stopped(p2))
  48. return (p2);
  49. if (p1->p_estcpu > p2->p_estcpu)
  50. return (p1);
  51. if (p1->p_estcpu < p2->p_estcpu)
  52. return (p2);
  53. if (p1->p_slptime < p2->p_slptime)
  54. return (p1);
  55. if (p1->p_slptime > p2->p_slptime)
  56. return (p2);
  57. if ((p1->p_flag & P_SINTR) && !(p2->p_flag & P_SINTR))
  58. return (p1);
  59. if (!(p1->p_flag & P_SINTR) && (p2->p_flag & P_SINTR))
  60. return (p2);
  61. if (strcmp(p1->p_comm, p2->p_comm) < 0)
  62. return (p1);
  63. if (strcmp(p1->p_comm, p2->p_comm) > 0)
  64. return (p2);
  65. if (p1->p_pid > p2->p_pid)
  66. return (p1);
  67. return (p2);
  68. }
  69. char *
  70. osdep_get_name(int fd, char *tty)
  71. {
  72. int mib[6] = { CTL_KERN, KERN_PROC, KERN_PROC_PGRP, 0,
  73. sizeof(struct kinfo_proc), 0 };
  74. struct stat sb;
  75. size_t len;
  76. struct kinfo_proc *buf, *newbuf, *bestp;
  77. u_int i;
  78. char *name;
  79. buf = NULL;
  80. if (stat(tty, &sb) == -1)
  81. return (NULL);
  82. if ((mib[3] = tcgetpgrp(fd)) == -1)
  83. return (NULL);
  84. retry:
  85. if (sysctl(mib, nitems(mib), NULL, &len, NULL, 0) == -1)
  86. goto error;
  87. len = (len * 5) / 4;
  88. if ((newbuf = realloc(buf, len)) == NULL)
  89. goto error;
  90. buf = newbuf;
  91. mib[5] = (int)(len / sizeof(struct kinfo_proc));
  92. if (sysctl(mib, nitems(mib), buf, &len, NULL, 0) == -1) {
  93. if (errno == ENOMEM)
  94. goto retry;
  95. goto error;
  96. }
  97. bestp = NULL;
  98. for (i = 0; i < len / sizeof (struct kinfo_proc); i++) {
  99. if ((dev_t)buf[i].p_tdev != sb.st_rdev)
  100. continue;
  101. if (bestp == NULL)
  102. bestp = &buf[i];
  103. else
  104. bestp = cmp_procs(&buf[i], bestp);
  105. }
  106. name = NULL;
  107. if (bestp != NULL)
  108. name = strdup(bestp->p_comm);
  109. free(buf);
  110. return (name);
  111. error:
  112. free(buf);
  113. return (NULL);
  114. }
  115. char *
  116. osdep_get_cwd(int fd)
  117. {
  118. int name[] = { CTL_KERN, KERN_PROC_CWD, 0 };
  119. static char path[MAXPATHLEN];
  120. size_t pathlen = sizeof path;
  121. if ((name[2] = tcgetpgrp(fd)) == -1)
  122. return (NULL);
  123. if (sysctl(name, 3, path, &pathlen, NULL, 0) != 0)
  124. return (NULL);
  125. return (path);
  126. }
  127. struct event_base *
  128. osdep_event_init(void)
  129. {
  130. return (event_init());
  131. }