]> git.ipfire.org Git - thirdparty/git.git/blob - t/helper/test-drop-caches.c
Sync with js/partial-urlmatch-2.17
[thirdparty/git.git] / t / helper / test-drop-caches.c
1 #include "test-tool.h"
2 #include "git-compat-util.h"
3
4 #if defined(GIT_WINDOWS_NATIVE)
5 #include "lazyload.h"
6
7 static int cmd_sync(void)
8 {
9 char Buffer[MAX_PATH];
10 DWORD dwRet;
11 char szVolumeAccessPath[] = "\\\\.\\XXXX:";
12 HANDLE hVolWrite;
13 int success = 0, dos_drive_prefix;
14
15 dwRet = GetCurrentDirectory(MAX_PATH, Buffer);
16 if ((0 == dwRet) || (dwRet > MAX_PATH))
17 return error("Error getting current directory");
18
19 dos_drive_prefix = has_dos_drive_prefix(Buffer);
20 if (!dos_drive_prefix)
21 return error("'%s': invalid drive letter", Buffer);
22
23 memcpy(szVolumeAccessPath, Buffer, dos_drive_prefix);
24 szVolumeAccessPath[dos_drive_prefix] = '\0';
25
26 hVolWrite = CreateFile(szVolumeAccessPath, GENERIC_READ | GENERIC_WRITE,
27 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
28 if (INVALID_HANDLE_VALUE == hVolWrite)
29 return error("Unable to open volume for writing, need admin access");
30
31 success = FlushFileBuffers(hVolWrite);
32 if (!success)
33 error("Unable to flush volume");
34
35 CloseHandle(hVolWrite);
36
37 return !success;
38 }
39
40 #define STATUS_SUCCESS (0x00000000L)
41 #define STATUS_PRIVILEGE_NOT_HELD (0xC0000061L)
42
43 typedef enum _SYSTEM_INFORMATION_CLASS {
44 SystemMemoryListInformation = 80,
45 } SYSTEM_INFORMATION_CLASS;
46
47 typedef enum _SYSTEM_MEMORY_LIST_COMMAND {
48 MemoryCaptureAccessedBits,
49 MemoryCaptureAndResetAccessedBits,
50 MemoryEmptyWorkingSets,
51 MemoryFlushModifiedList,
52 MemoryPurgeStandbyList,
53 MemoryPurgeLowPriorityStandbyList,
54 MemoryCommandMax
55 } SYSTEM_MEMORY_LIST_COMMAND;
56
57 static BOOL GetPrivilege(HANDLE TokenHandle, LPCSTR lpName, int flags)
58 {
59 BOOL bResult;
60 DWORD dwBufferLength;
61 LUID luid;
62 TOKEN_PRIVILEGES tpPreviousState;
63 TOKEN_PRIVILEGES tpNewState;
64
65 dwBufferLength = 16;
66 bResult = LookupPrivilegeValueA(0, lpName, &luid);
67 if (bResult) {
68 tpNewState.PrivilegeCount = 1;
69 tpNewState.Privileges[0].Luid = luid;
70 tpNewState.Privileges[0].Attributes = 0;
71 bResult = AdjustTokenPrivileges(TokenHandle, 0, &tpNewState,
72 (DWORD)((LPBYTE)&(tpNewState.Privileges[1]) - (LPBYTE)&tpNewState),
73 &tpPreviousState, &dwBufferLength);
74 if (bResult) {
75 tpPreviousState.PrivilegeCount = 1;
76 tpPreviousState.Privileges[0].Luid = luid;
77 tpPreviousState.Privileges[0].Attributes = flags != 0 ? 2 : 0;
78 bResult = AdjustTokenPrivileges(TokenHandle, 0, &tpPreviousState,
79 dwBufferLength, 0, 0);
80 }
81 }
82 return bResult;
83 }
84
85 static int cmd_dropcaches(void)
86 {
87 HANDLE hProcess = GetCurrentProcess();
88 HANDLE hToken;
89 DECLARE_PROC_ADDR(ntdll.dll, DWORD, NtSetSystemInformation, INT, PVOID, ULONG);
90 SYSTEM_MEMORY_LIST_COMMAND command;
91 int status;
92
93 if (!OpenProcessToken(hProcess, TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken))
94 return error("Can't open current process token");
95
96 if (!GetPrivilege(hToken, "SeProfileSingleProcessPrivilege", 1))
97 return error("Can't get SeProfileSingleProcessPrivilege");
98
99 CloseHandle(hToken);
100
101 if (!INIT_PROC_ADDR(NtSetSystemInformation))
102 return error("Could not find NtSetSystemInformation() function");
103
104 command = MemoryPurgeStandbyList;
105 status = NtSetSystemInformation(
106 SystemMemoryListInformation,
107 &command,
108 sizeof(SYSTEM_MEMORY_LIST_COMMAND)
109 );
110 if (status == STATUS_PRIVILEGE_NOT_HELD)
111 error("Insufficient privileges to purge the standby list, need admin access");
112 else if (status != STATUS_SUCCESS)
113 error("Unable to execute the memory list command %d", status);
114
115 return status;
116 }
117
118 #elif defined(__linux__)
119
120 static int cmd_sync(void)
121 {
122 return system("sync");
123 }
124
125 static int cmd_dropcaches(void)
126 {
127 return system("echo 3 | sudo tee /proc/sys/vm/drop_caches");
128 }
129
130 #elif defined(__APPLE__)
131
132 static int cmd_sync(void)
133 {
134 return system("sync");
135 }
136
137 static int cmd_dropcaches(void)
138 {
139 return system("sudo purge");
140 }
141
142 #else
143
144 static int cmd_sync(void)
145 {
146 return 0;
147 }
148
149 static int cmd_dropcaches(void)
150 {
151 return error("drop caches not implemented on this platform");
152 }
153
154 #endif
155
156 int cmd__drop_caches(int argc, const char **argv)
157 {
158 cmd_sync();
159 return cmd_dropcaches();
160 }