blob: 57596156fb5996e71dc62fecee03a93ee8d95966 [file] [log] [blame]
Benny Baumann18763052020-11-11 22:15:35 +01001/*
2htop - ProcessLocksScreen.c
3(C) 2020 htop dev team
4Released under the GNU GPLv2, see the COPYING file
5in the source distribution for its full text.
6*/
7
8#include "config.h" // IWYU pragma: keep
9
10#include "ProcessLocksScreen.h"
11
Benny Baumann18763052020-11-11 22:15:35 +010012#include <inttypes.h>
13#include <limits.h>
Benny Baumann18763052020-11-11 22:15:35 +010014#include <stdlib.h>
Benny Baumann18763052020-11-11 22:15:35 +010015
Christian Göttsche7cf52772020-11-18 14:26:30 +010016#include "Panel.h"
Benny Baumann18763052020-11-11 22:15:35 +010017#include "Platform.h"
Christian Göttsche7cf52772020-11-18 14:26:30 +010018#include "ProvideCurses.h"
19#include "Vector.h"
Benny Baumann18763052020-11-11 22:15:35 +010020#include "XUtils.h"
21
22
23ProcessLocksScreen* ProcessLocksScreen_new(const Process* process) {
24 ProcessLocksScreen* this = xMalloc(sizeof(ProcessLocksScreen));
25 Object_setClass(this, Class(ProcessLocksScreen));
26 if (Process_isThread(process))
27 this->pid = process->tgid;
28 else
29 this->pid = process->pid;
Daniel Lange1ffe5d72021-01-11 12:53:07 +010030 return (ProcessLocksScreen*) InfoScreen_init(&this->super, process, NULL, LINES - 2, " ID TYPE EXCLUSION READ/WRITE DEVICE:INODE START END FILENAME");
Benny Baumann18763052020-11-11 22:15:35 +010031}
32
33void ProcessLocksScreen_delete(Object* this) {
34 free(InfoScreen_done((InfoScreen*)this));
35}
36
37static void ProcessLocksScreen_draw(InfoScreen* this) {
Christian Göttsche1d5b0522020-11-25 12:43:30 +010038 InfoScreen_drawTitled(this, "Snapshot of file locks of process %d - %s", ((ProcessLocksScreen*)this)->pid, Process_getCommand(this->process));
Benny Baumann18763052020-11-11 22:15:35 +010039}
40
41static inline void FileLocks_Data_clear(FileLocks_Data* data) {
Benny Baumannd4317862020-11-13 21:34:21 +010042 free(data->locktype);
43 free(data->exclusive);
44 free(data->readwrite);
45 free(data->filename);
Benny Baumann18763052020-11-11 22:15:35 +010046}
47
48static void ProcessLocksScreen_scan(InfoScreen* this) {
49 Panel* panel = this->display;
50 int idx = Panel_getSelectedIndex(panel);
51 Panel_prune(panel);
52 FileLocks_ProcessData* pdata = Platform_getProcessLocks(((ProcessLocksScreen*)this)->pid);
53 if (!pdata) {
54 InfoScreen_addLine(this, "This feature is not supported on your platform.");
55 } else if (pdata->error) {
56 InfoScreen_addLine(this, "Could not determine file locks.");
57 } else {
58 FileLocks_LockData* ldata = pdata->locks;
59 if (!ldata) {
60 InfoScreen_addLine(this, "No locks have been found for the selected process.");
61 }
62 while (ldata) {
63 FileLocks_Data* data = &ldata->data;
64
65 char entry[512];
66 if (ULLONG_MAX == data->end) {
67 xSnprintf(entry, sizeof(entry), "%10d %-10s %-10s %-10s %02x:%02x:%020"PRIu64" %20"PRIu64" %20s %s",
68 data->id,
Benny Baumannd4317862020-11-13 21:34:21 +010069 data->locktype, data->exclusive, data->readwrite,
Benny Baumann18763052020-11-11 22:15:35 +010070 data->dev[0], data->dev[1], data->inode,
71 data->start, "<END OF FILE>",
Benny Baumannd4317862020-11-13 21:34:21 +010072 data->filename ? data->filename : "<N/A>"
Benny Baumann18763052020-11-11 22:15:35 +010073 );
74 } else {
75 xSnprintf(entry, sizeof(entry), "%10d %-10s %-10s %-10s %02x:%02x:%020"PRIu64" %20"PRIu64" %20"PRIu64" %s",
76 data->id,
Benny Baumannd4317862020-11-13 21:34:21 +010077 data->locktype, data->exclusive, data->readwrite,
Benny Baumann18763052020-11-11 22:15:35 +010078 data->dev[0], data->dev[1], data->inode,
79 data->start, data->end,
Benny Baumannd4317862020-11-13 21:34:21 +010080 data->filename ? data->filename : "<N/A>"
Benny Baumann18763052020-11-11 22:15:35 +010081 );
82 }
83
84 InfoScreen_addLine(this, entry);
85 FileLocks_Data_clear(&ldata->data);
86
87 FileLocks_LockData* old = ldata;
88 ldata = ldata->next;
89 free(old);
90 }
91 }
92 free(pdata);
93 Vector_insertionSort(this->lines);
94 Vector_insertionSort(panel->items);
95 Panel_setSelected(panel, idx);
96}
97
98const InfoScreenClass ProcessLocksScreen_class = {
99 .super = {
100 .extends = Class(Object),
101 .delete = ProcessLocksScreen_delete
102 },
103 .scan = ProcessLocksScreen_scan,
104 .draw = ProcessLocksScreen_draw
105};