2 #include "git-compat-util.h"
4 #if defined(GIT_WINDOWS_NATIVE)
8 static int cmd_sync(void)
10 char Buffer
[MAX_PATH
];
12 char szVolumeAccessPath
[] = "\\\\.\\XXXX:";
14 int success
= 0, dos_drive_prefix
;
16 dwRet
= GetCurrentDirectory(MAX_PATH
, Buffer
);
17 if ((0 == dwRet
) || (dwRet
> MAX_PATH
))
18 return error("Error getting current directory");
20 dos_drive_prefix
= has_dos_drive_prefix(Buffer
);
21 if (!dos_drive_prefix
)
22 return error("'%s': invalid drive letter", Buffer
);
24 memcpy(szVolumeAccessPath
, Buffer
, dos_drive_prefix
);
25 szVolumeAccessPath
[dos_drive_prefix
] = '\0';
27 hVolWrite
= CreateFile(szVolumeAccessPath
, GENERIC_READ
| GENERIC_WRITE
,
28 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
, 0, NULL
);
29 if (INVALID_HANDLE_VALUE
== hVolWrite
)
30 return error("Unable to open volume for writing, need admin access");
32 success
= FlushFileBuffers(hVolWrite
);
34 error("Unable to flush volume");
36 CloseHandle(hVolWrite
);
41 #define STATUS_SUCCESS (0x00000000L)
42 #define STATUS_PRIVILEGE_NOT_HELD (0xC0000061L)
44 typedef enum _SYSTEM_INFORMATION_CLASS
{
45 SystemMemoryListInformation
= 80,
46 } SYSTEM_INFORMATION_CLASS
;
48 typedef enum _SYSTEM_MEMORY_LIST_COMMAND
{
49 MemoryCaptureAccessedBits
,
50 MemoryCaptureAndResetAccessedBits
,
51 MemoryEmptyWorkingSets
,
52 MemoryFlushModifiedList
,
53 MemoryPurgeStandbyList
,
54 MemoryPurgeLowPriorityStandbyList
,
56 } SYSTEM_MEMORY_LIST_COMMAND
;
58 static BOOL
GetPrivilege(HANDLE TokenHandle
, LPCSTR lpName
, int flags
)
63 TOKEN_PRIVILEGES tpPreviousState
;
64 TOKEN_PRIVILEGES tpNewState
;
67 bResult
= LookupPrivilegeValueA(0, lpName
, &luid
);
69 tpNewState
.PrivilegeCount
= 1;
70 tpNewState
.Privileges
[0].Luid
= luid
;
71 tpNewState
.Privileges
[0].Attributes
= 0;
72 bResult
= AdjustTokenPrivileges(TokenHandle
, 0, &tpNewState
,
73 (DWORD
)((LPBYTE
)&(tpNewState
.Privileges
[1]) - (LPBYTE
)&tpNewState
),
74 &tpPreviousState
, &dwBufferLength
);
76 tpPreviousState
.PrivilegeCount
= 1;
77 tpPreviousState
.Privileges
[0].Luid
= luid
;
78 tpPreviousState
.Privileges
[0].Attributes
= flags
!= 0 ? 2 : 0;
79 bResult
= AdjustTokenPrivileges(TokenHandle
, 0, &tpPreviousState
,
80 dwBufferLength
, 0, 0);
86 static int cmd_dropcaches(void)
88 HANDLE hProcess
= GetCurrentProcess();
90 DECLARE_PROC_ADDR(ntdll
.dll
, DWORD
, NTAPI
, NtSetSystemInformation
, INT
, PVOID
,
92 SYSTEM_MEMORY_LIST_COMMAND command
;
95 if (!OpenProcessToken(hProcess
, TOKEN_QUERY
| TOKEN_ADJUST_PRIVILEGES
, &hToken
))
96 return error("Can't open current process token");
98 if (!GetPrivilege(hToken
, "SeProfileSingleProcessPrivilege", 1))
99 return error("Can't get SeProfileSingleProcessPrivilege");
103 if (!INIT_PROC_ADDR(NtSetSystemInformation
))
104 return error("Could not find NtSetSystemInformation() function");
106 command
= MemoryPurgeStandbyList
;
107 status
= NtSetSystemInformation(
108 SystemMemoryListInformation
,
110 sizeof(SYSTEM_MEMORY_LIST_COMMAND
)
112 if (status
== STATUS_PRIVILEGE_NOT_HELD
)
113 error("Insufficient privileges to purge the standby list, need admin access");
114 else if (status
!= STATUS_SUCCESS
)
115 error("Unable to execute the memory list command %d", status
);
120 #elif defined(__linux__)
122 static int cmd_sync(void)
124 return system("sync");
127 static int cmd_dropcaches(void)
129 return system("echo 3 | sudo tee /proc/sys/vm/drop_caches");
132 #elif defined(__APPLE__)
134 static int cmd_sync(void)
136 return system("sync");
139 static int cmd_dropcaches(void)
141 return system("sudo purge");
146 static int cmd_sync(void)
151 static int cmd_dropcaches(void)
153 return error("drop caches not implemented on this platform");
158 int cmd__drop_caches(int argc UNUSED
, const char **argv UNUSED
)
161 return cmd_dropcaches();