1 #include "git-compat-util.h"
3 #if defined(GIT_WINDOWS_NATIVE)
5 static int cmd_sync(void)
9 char szVolumeAccessPath[] = "\\\\.\\XXXX:";
11 int success = 0, dos_drive_prefix;
13 dwRet = GetCurrentDirectory(MAX_PATH, Buffer);
14 if ((0 == dwRet) || (dwRet > MAX_PATH))
15 return error("Error getting current directory");
17 dos_drive_prefix = has_dos_drive_prefix(Buffer);
18 if (!dos_drive_prefix)
19 return error("'%s': invalid drive letter", Buffer);
21 memcpy(szVolumeAccessPath, Buffer, dos_drive_prefix);
22 szVolumeAccessPath[dos_drive_prefix] = '\0';
24 hVolWrite = CreateFile(szVolumeAccessPath, GENERIC_READ | GENERIC_WRITE,
25 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
26 if (INVALID_HANDLE_VALUE == hVolWrite)
27 return error("Unable to open volume for writing, need admin access");
29 success = FlushFileBuffers(hVolWrite);
31 error("Unable to flush volume");
33 CloseHandle(hVolWrite);
38 #define STATUS_SUCCESS (0x00000000L)
39 #define STATUS_PRIVILEGE_NOT_HELD (0xC0000061L)
41 typedef enum _SYSTEM_INFORMATION_CLASS {
42 SystemMemoryListInformation = 80,
43 } SYSTEM_INFORMATION_CLASS;
45 typedef enum _SYSTEM_MEMORY_LIST_COMMAND {
46 MemoryCaptureAccessedBits,
47 MemoryCaptureAndResetAccessedBits,
48 MemoryEmptyWorkingSets,
49 MemoryFlushModifiedList,
50 MemoryPurgeStandbyList,
51 MemoryPurgeLowPriorityStandbyList,
53 } SYSTEM_MEMORY_LIST_COMMAND;
55 static BOOL GetPrivilege(HANDLE TokenHandle, LPCSTR lpName, int flags)
60 TOKEN_PRIVILEGES tpPreviousState;
61 TOKEN_PRIVILEGES tpNewState;
64 bResult = LookupPrivilegeValueA(0, lpName, &luid);
66 tpNewState.PrivilegeCount = 1;
67 tpNewState.Privileges[0].Luid = luid;
68 tpNewState.Privileges[0].Attributes = 0;
69 bResult = AdjustTokenPrivileges(TokenHandle, 0, &tpNewState,
70 (DWORD)((LPBYTE)&(tpNewState.Privileges[1]) - (LPBYTE)&tpNewState),
71 &tpPreviousState, &dwBufferLength);
73 tpPreviousState.PrivilegeCount = 1;
74 tpPreviousState.Privileges[0].Luid = luid;
75 tpPreviousState.Privileges[0].Attributes = flags != 0 ? 2 : 0;
76 bResult = AdjustTokenPrivileges(TokenHandle, 0, &tpPreviousState,
77 dwBufferLength, 0, 0);
83 static int cmd_dropcaches(void)
85 HANDLE hProcess = GetCurrentProcess();
88 DWORD(WINAPI *NtSetSystemInformation)(INT, PVOID, ULONG);
89 SYSTEM_MEMORY_LIST_COMMAND command;
92 if (!OpenProcessToken(hProcess, TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken))
93 return error("Can't open current process token");
95 if (!GetPrivilege(hToken, "SeProfileSingleProcessPrivilege", 1))
96 return error("Can't get SeProfileSingleProcessPrivilege");
100 ntdll = LoadLibrary("ntdll.dll");
102 return error("Can't load ntdll.dll, wrong Windows version?");
104 NtSetSystemInformation =
105 (DWORD(WINAPI *)(INT, PVOID, ULONG))GetProcAddress(ntdll, "NtSetSystemInformation");
106 if (!NtSetSystemInformation)
107 return error("Can't get function addresses, wrong Windows version?");
109 command = MemoryPurgeStandbyList;
110 status = NtSetSystemInformation(
111 SystemMemoryListInformation,
113 sizeof(SYSTEM_MEMORY_LIST_COMMAND)
115 if (status == STATUS_PRIVILEGE_NOT_HELD)
116 error("Insufficient privileges to purge the standby list, need admin access");
117 else if (status != STATUS_SUCCESS)
118 error("Unable to execute the memory list command %d", status);
125 #elif defined(__linux__)
127 static int cmd_sync(void)
129 return system("sync");
132 static int cmd_dropcaches(void)
134 return system("echo 3 | sudo tee /proc/sys/vm/drop_caches");
137 #elif defined(__APPLE__)
139 static int cmd_sync(void)
141 return system("sync");
144 static int cmd_dropcaches(void)
146 return system("sudo purge");
151 static int cmd_sync(void)
156 static int cmd_dropcaches(void)
158 return error("drop caches not implemented on this platform");
163 int cmd_main(int argc, const char **argv)
166 return cmd_dropcaches();