ProcessLocksScreen.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /*
  2. htop - ProcessLocksScreen.c
  3. (C) 2020 htop dev team
  4. Released under the GNU GPLv2+, see the COPYING file
  5. in the source distribution for its full text.
  6. */
  7. #include "config.h" // IWYU pragma: keep
  8. #include "ProcessLocksScreen.h"
  9. #include <inttypes.h>
  10. #include <limits.h>
  11. #include <stdlib.h>
  12. #include "Panel.h"
  13. #include "Platform.h"
  14. #include "ProvideCurses.h"
  15. #include "Vector.h"
  16. #include "XUtils.h"
  17. ProcessLocksScreen* ProcessLocksScreen_new(const Process* process) {
  18. ProcessLocksScreen* this = xMalloc(sizeof(ProcessLocksScreen));
  19. Object_setClass(this, Class(ProcessLocksScreen));
  20. if (Process_isThread(process))
  21. this->pid = Process_getThreadGroup(process);
  22. else
  23. this->pid = Process_getPid(process);
  24. return (ProcessLocksScreen*) InfoScreen_init(&this->super, process, NULL, LINES - 2, " FD TYPE EXCLUSION READ/WRITE DEVICE NODE START END FILENAME");
  25. }
  26. void ProcessLocksScreen_delete(Object* this) {
  27. free(InfoScreen_done((InfoScreen*)this));
  28. }
  29. static void ProcessLocksScreen_draw(InfoScreen* this) {
  30. InfoScreen_drawTitled(this, "Snapshot of file locks of process %d - %s", ((ProcessLocksScreen*)this)->pid, Process_getCommand(this->process));
  31. }
  32. static inline void FileLocks_Data_clear(FileLocks_Data* data) {
  33. free(data->locktype);
  34. free(data->exclusive);
  35. free(data->readwrite);
  36. free(data->filename);
  37. }
  38. static void ProcessLocksScreen_scan(InfoScreen* this) {
  39. Panel* panel = this->display;
  40. int idx = Panel_getSelectedIndex(panel);
  41. Panel_prune(panel);
  42. FileLocks_ProcessData* pdata = Platform_getProcessLocks(((ProcessLocksScreen*)this)->pid);
  43. if (!pdata) {
  44. InfoScreen_addLine(this, "This feature is not supported on your platform.");
  45. } else if (pdata->error) {
  46. InfoScreen_addLine(this, "Could not determine file locks.");
  47. } else {
  48. FileLocks_LockData* ldata = pdata->locks;
  49. if (!ldata) {
  50. InfoScreen_addLine(this, "No locks have been found for the selected process.");
  51. }
  52. while (ldata) {
  53. FileLocks_Data* data = &ldata->data;
  54. char entry[512];
  55. if (ULLONG_MAX == data->end) {
  56. xSnprintf(entry, sizeof(entry), "%5d %-10s %-10s %-10s %#6"PRIx64" %10"PRIu64" %19"PRIu64" %19s %s",
  57. data->fd,
  58. data->locktype, data->exclusive, data->readwrite,
  59. (uint64_t) data->dev, data->inode,
  60. data->start, "<END OF FILE>",
  61. data->filename ? data->filename : "<N/A>"
  62. );
  63. } else {
  64. xSnprintf(entry, sizeof(entry), "%5d %-10s %-10s %-10s %#6"PRIx64" %10"PRIu64" %19"PRIu64" %19"PRIu64" %s",
  65. data->fd,
  66. data->locktype, data->exclusive, data->readwrite,
  67. (uint64_t) data->dev, data->inode,
  68. data->start, data->end,
  69. data->filename ? data->filename : "<N/A>"
  70. );
  71. }
  72. InfoScreen_addLine(this, entry);
  73. FileLocks_Data_clear(&ldata->data);
  74. FileLocks_LockData* old = ldata;
  75. ldata = ldata->next;
  76. free(old);
  77. }
  78. }
  79. free(pdata);
  80. Vector_insertionSort(this->lines);
  81. Vector_insertionSort(panel->items);
  82. Panel_setSelected(panel, idx);
  83. }
  84. const InfoScreenClass ProcessLocksScreen_class = {
  85. .super = {
  86. .extends = Class(Object),
  87. .delete = ProcessLocksScreen_delete
  88. },
  89. .scan = ProcessLocksScreen_scan,
  90. .draw = ProcessLocksScreen_draw
  91. };