Skip to content

Commit 3846d77

Browse files
author
Chung-Yu Liao
committed
Initial Windows support.
1 parent 0c21876 commit 3846d77

File tree

5 files changed

+155
-8
lines changed

5 files changed

+155
-8
lines changed

include/nvtop/get_process_info.h

+5
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@
2222
#ifndef __GET_PROCESS_INFO_H_
2323
#define __GET_PROCESS_INFO_H_
2424

25+
#ifdef _WIN32
26+
#include <windef.h>
27+
#define pid_t DWORD
28+
#endif
29+
2530
#include <stdlib.h>
2631

2732
void get_username_from_pid(pid_t pid, size_t size_buffer, char *buffer);

src/CMakeLists.txt

+20-7
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,33 @@ configure_file(
33
"${PROJECT_BINARY_DIR}/include/nvtop/version.h"
44
IMMEDIATE @ONLY)
55

6-
add_executable (nvtop
7-
nvtop.c
8-
interface.c
9-
get_process_info_linux.c
10-
extract_gpuinfo.c)
6+
if(MINGW)
7+
add_executable(nvtop
8+
nvtop.c
9+
interface.c
10+
get_process_info_windows.c
11+
extract_gpuinfo.c)
12+
else()
13+
add_executable(nvtop
14+
nvtop.c
15+
interface.c
16+
get_process_info_linux.c
17+
extract_gpuinfo.c)
18+
endif()
1119

1220
target_include_directories(nvtop PRIVATE
1321
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
1422
$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/include>)
1523

1624
set_property(TARGET nvtop PROPERTY C_STANDARD 11)
1725

18-
target_link_libraries(nvtop
19-
PRIVATE nvml ncurses m)
26+
if(MINGW)
27+
target_link_libraries(nvtop
28+
PRIVATE nvml ncurses m)
29+
else()
30+
target_link_libraries(nvtop
31+
PRIVATE nvml ncurses m "-Wl,-Bstatic")
32+
endif()
2033

2134
install (TARGETS nvtop
2235
RUNTIME DESTINATION bin)

src/get_process_info_windows.c

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
*
3+
* Copyright (C) 2019 Chung-Yu Liao <[email protected]>
4+
*
5+
* This file is part of Nvtop.
6+
*
7+
* Nvtop is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation, either version 3 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* Nvtop is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with nvtop. If not, see <http://www.gnu.org/licenses/>.
19+
*
20+
*/
21+
22+
#include "nvtop/get_process_info.h"
23+
24+
#include <stdio.h>
25+
#include <string.h>
26+
#include <winbase.h>
27+
#include <sddl.h>
28+
29+
void get_username_from_pid(pid_t pid, size_t size_buffer, char *buffer) {
30+
HANDLE hProc = NULL;
31+
HANDLE hProcToken = NULL;
32+
DWORD dwTokenSize = 0u;
33+
34+
PTOKEN_USER pTokenUser = NULL;
35+
LPSTR lpStringSid = NULL;
36+
37+
buffer[0] = '\0';
38+
39+
hProc = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_VM_READ, FALSE, pid);
40+
41+
if (!OpenProcessToken(hProc, TOKEN_QUERY, hProcToken)) {
42+
return;
43+
}
44+
45+
if (!GetTokenInformation(hProcToken, TokenUser, NULL, dwTokenSize, &dwTokenSize)){
46+
CloseHandle(hProcToken);
47+
return;
48+
}
49+
pTokenUser = (TOKEN_USER *)LocalAlloc(LMEM_FIXED, dwTokenSize);
50+
if (!GetTokenInformation(hProcToken, TokenUser, pTokenUser, dwTokenSize, &dwTokenSize)){
51+
LocalFree(pTokenUser);
52+
CloseHandle(hProcToken);
53+
return;
54+
}
55+
56+
if (!ConvertSidToStringSid(pTokenUser->User.Sid, &lpStringSid)) {
57+
LocalFree(pTokenUser);
58+
CloseHandle(hProcToken);
59+
CloseHandle(hProc);
60+
return;
61+
}
62+
strncpy(buffer, lpStringSid, size_buffer);
63+
64+
LocalFree(lpStringSid);
65+
LocalFree(pTokenUser);
66+
CloseHandle(hProcToken);
67+
CloseHandle(hProc);
68+
}

src/interface.c

+37-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@
1919
*
2020
*/
2121

22+
#ifdef _WIN32
23+
#define __USE_MINGW_ANSI_STDIO 1
24+
#define pid_t DWORD
25+
#include <windef.h>
26+
#include <winbase.h>
27+
#endif
28+
2229
#include "nvtop/interface.h"
2330

2431
#include <stdlib.h>
@@ -988,6 +995,26 @@ static void draw_processes(
988995
print_processes_on_screen(total_processes, &interface->process);
989996
}
990997

998+
#ifdef _WIN32
999+
static const char *signalsName[] = {
1000+
"Cancel",
1001+
"SIGABRT",
1002+
"SIGFPE",
1003+
"SIGILL",
1004+
"SIGINT",
1005+
"SIGSEGV",
1006+
"SIGTERM",
1007+
};
1008+
1009+
static const int signalsValues[] = {
1010+
SIGABRT,
1011+
SIGFPE ,
1012+
SIGILL ,
1013+
SIGINT ,
1014+
SIGSEGV,
1015+
SIGTERM,
1016+
};
1017+
#else
9911018
static const char *signalsName[] = {
9921019
"Cancel",
9931020
"SIGABRT",
@@ -1050,6 +1077,7 @@ SIGVTALRM,
10501077
SIGXCPU ,
10511078
SIGXFSZ ,
10521079
};
1080+
#endif
10531081

10541082
static const size_t nvtop_num_signals = 28;
10551083

@@ -1272,7 +1300,15 @@ static void option_do_kill(struct nvtop_interface *inter) {
12721300
return;
12731301
pid_t pid = inter->process.all_process[inter->process.selected_row].pid;
12741302
int sig = signalsValues[inter->option_window.selected_row-1];
1275-
kill(pid,sig);
1303+
1304+
#ifdef _WIN32
1305+
HANDLE hProc;
1306+
hProc = OpenProcess(PROCESS_TERMINATE, false, pid);
1307+
TerminateProcess(hProc, sig);
1308+
CloseHandle(hProc);
1309+
#else
1310+
kill(pid, sig);
1311+
#endif
12761312
}
12771313

12781314
static void option_change_sort(struct nvtop_interface *inter) {

src/nvtop.c

+25
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,17 @@
1919
*
2020
*/
2121

22+
#ifdef _WIN32
23+
#define __USE_MINGW_ANSI_STDIO 1
24+
#define setenv(name, value, overwrite) \
25+
_putenv_s(name, value)
26+
#include <windef.h>
27+
#include <winbase.h>
28+
#include <wincon.h>
29+
#include <winnls.h>
30+
#include <fcntl.h>
31+
#endif
32+
2233
#include <signal.h>
2334
#include <stdio.h>
2435
#include <stdlib.h>
@@ -42,10 +53,12 @@ static void exit_handler(int signum) {
4253
signal_bits |= STOP_SIGNAL;
4354
}
4455

56+
#ifndef _WIN32
4557
static void resize_handler(int signum) {
4658
(void) signum;
4759
signal_bits |= RESIZE_SIGNAL;
4860
}
61+
#endif
4962

5063
static const char helpstring[] =
5164
"Available options:\n"
@@ -136,7 +149,12 @@ static size_t update_mask_value(const char *str, size_t entry_mask, bool addTo)
136149
}
137150

138151
int main (int argc, char **argv) {
152+
#ifdef _WIN32
153+
SetConsoleCP(CP_UTF8);
154+
SetConsoleOutputCP(CP_UTF8);
155+
#else
139156
(void) setlocale(LC_CTYPE, "");
157+
#endif
140158

141159
opterr = 0;
142160
int refresh_interval = 1000;
@@ -195,6 +213,12 @@ int main (int argc, char **argv) {
195213

196214
setenv("ESCDELAY", "10", 1);
197215

216+
#ifdef _WIN32
217+
if (signal(SIGINT, exit_handler) == SIG_ERR) {
218+
perror("Impossible to set signal handler for SIGINT: ");
219+
exit(EXIT_FAILURE);
220+
}
221+
#else
198222
struct sigaction siga;
199223
siga.sa_flags = 0;
200224
sigemptyset(&siga.sa_mask);
@@ -213,6 +237,7 @@ int main (int argc, char **argv) {
213237
perror("Impossible to set signal handler for SIGQUIT: ");
214238
exit(EXIT_FAILURE);
215239
}
240+
#endif
216241

217242
size_t gpu_mask;
218243
if (selectedGPU != NULL) {

0 commit comments

Comments
 (0)