2 #include "git-compat-util.h"
4 #if defined(GIT_WINDOWS_NATIVE)
6 static int cmd_sync(void)
10 char szVolumeAccessPath
[] = "\\\\.\\X:";
14 dwRet
= GetCurrentDirectory(MAX_PATH
, Buffer
);
15 if ((0 == dwRet
) || (dwRet
> MAX_PATH
))
16 return error("Error getting current directory");
18 if ((Buffer
[0] < 'A') || (Buffer
[0] > 'Z'))
19 return error("Invalid drive letter '%c'", Buffer
[0]);
21 szVolumeAccessPath
[4] = Buffer
[0];
22 hVolWrite
= CreateFile(szVolumeAccessPath
, GENERIC_READ
| GENERIC_WRITE
,
23 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
, 0, NULL
);
24 if (INVALID_HANDLE_VALUE
== hVolWrite
)
25 return error("Unable to open volume for writing, need admin access");
27 success
= FlushFileBuffers(hVolWrite
);
29 error("Unable to flush volume");
31 CloseHandle(hVolWrite
);
36 #define STATUS_SUCCESS (0x00000000L)
37 #define STATUS_PRIVILEGE_NOT_HELD (0xC0000061L)
39 typedef enum _SYSTEM_INFORMATION_CLASS
{
40 SystemMemoryListInformation
= 80,
41 } SYSTEM_INFORMATION_CLASS
;
43 typedef enum _SYSTEM_MEMORY_LIST_COMMAND
{
44 MemoryCaptureAccessedBits
,
45 MemoryCaptureAndResetAccessedBits
,
46 MemoryEmptyWorkingSets
,
47 MemoryFlushModifiedList
,
48 MemoryPurgeStandbyList
,
49 MemoryPurgeLowPriorityStandbyList
,
51 } SYSTEM_MEMORY_LIST_COMMAND
;
53 static BOOL
GetPrivilege(HANDLE TokenHandle
, LPCSTR lpName
, int flags
)
58 TOKEN_PRIVILEGES tpPreviousState
;
59 TOKEN_PRIVILEGES tpNewState
;
62 bResult
= LookupPrivilegeValueA(0, lpName
, &luid
);
64 tpNewState
.PrivilegeCount
= 1;
65 tpNewState
.Privileges
[0].Luid
= luid
;
66 tpNewState
.Privileges
[0].Attributes
= 0;
67 bResult
= AdjustTokenPrivileges(TokenHandle
, 0, &tpNewState
,
68 (DWORD
)((LPBYTE
)&(tpNewState
.Privileges
[1]) - (LPBYTE
)&tpNewState
),
69 &tpPreviousState
, &dwBufferLength
);
71 tpPreviousState
.PrivilegeCount
= 1;
72 tpPreviousState
.Privileges
[0].Luid
= luid
;
73 tpPreviousState
.Privileges
[0].Attributes
= flags
!= 0 ? 2 : 0;
74 bResult
= AdjustTokenPrivileges(TokenHandle
, 0, &tpPreviousState
,
75 dwBufferLength
, 0, 0);
81 static int cmd_dropcaches(void)
83 HANDLE hProcess
= GetCurrentProcess();
86 DWORD(WINAPI
*NtSetSystemInformation
)(INT
, PVOID
, ULONG
);
87 SYSTEM_MEMORY_LIST_COMMAND command
;
90 if (!OpenProcessToken(hProcess
, TOKEN_QUERY
| TOKEN_ADJUST_PRIVILEGES
, &hToken
))
91 return error("Can't open current process token");
93 if (!GetPrivilege(hToken
, "SeProfileSingleProcessPrivilege", 1))
94 return error("Can't get SeProfileSingleProcessPrivilege");
98 ntdll
= LoadLibrary("ntdll.dll");
100 return error("Can't load ntdll.dll, wrong Windows version?");
102 NtSetSystemInformation
=
103 (DWORD(WINAPI
*)(INT
, PVOID
, ULONG
))GetProcAddress(ntdll
, "NtSetSystemInformation");
104 if (!NtSetSystemInformation
)
105 return error("Can't get function addresses, wrong Windows version?");
107 command
= MemoryPurgeStandbyList
;
108 status
= NtSetSystemInformation(
109 SystemMemoryListInformation
,
111 sizeof(SYSTEM_MEMORY_LIST_COMMAND
)
113 if (status
== STATUS_PRIVILEGE_NOT_HELD
)
114 error("Insufficient privileges to purge the standby list, need admin access");
115 else if (status
!= STATUS_SUCCESS
)
116 error("Unable to execute the memory list command %d", status
);
123 #elif defined(__linux__)
125 static int cmd_sync(void)
127 return system("sync");
130 static int cmd_dropcaches(void)
132 return system("echo 3 | sudo tee /proc/sys/vm/drop_caches");
135 #elif defined(__APPLE__)
137 static int cmd_sync(void)
139 return system("sync");
142 static int cmd_dropcaches(void)
144 return system("sudo purge");
149 static int cmd_sync(void)
154 static int cmd_dropcaches(void)
156 return error("drop caches not implemented on this platform");
161 int cmd__drop_caches(int argc
, const char **argv
)
164 return cmd_dropcaches();