From c49d250d45962698bbdb731e0b96e7db17b4aa06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Grubbstr=C3=B6m=20=28Grubba=29?= <grubba@grubba.org> Date: Wed, 5 Sep 2012 14:10:51 +0200 Subject: [PATCH] System: Added sync(). --- src/modules/system/configure.in | 2 +- src/modules/system/system.c | 62 +++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/src/modules/system/configure.in b/src/modules/system/configure.in index 67fc074dd4..a3fed2363c 100644 --- a/src/modules/system/configure.in +++ b/src/modules/system/configure.in @@ -92,7 +92,7 @@ AC_HAVE_FUNCS(syslog link symlink readlink resolvepath realpath chown lchown \ getpwnam getspnam getgrnam getpwuid getgrgid \ getgrent setgrent endgrent getpwent setpwent endpwent \ gethostname gethostbyname getservbyname \ - chroot fchroot uname sysinfo \ + chroot fchroot uname sysinfo sync \ getgrnam_r getgrent_r getgrgid_r \ getpwnam_r getpwent_r getpwuid_r \ getspnam_r innetgr utime _utime lutimes sleep usleep nanosleep \ diff --git a/src/modules/system/system.c b/src/modules/system/system.c index 72f16aa270..93bbf69fe6 100644 --- a/src/modules/system/system.c +++ b/src/modules/system/system.c @@ -690,6 +690,64 @@ void f_utime(INT32 args) } #endif +#if !defined(HAVE_SYNC) && defined(__NT__) +static void sync(void) +{ + /* NB: For some stupid reason FindFirstVolume()/FindNextVolume() + * will only list local filesystems. So we have to fall + * back to using GetLogicalDrives(). + */ + /* NB: \\.\ is the DOS device namespace prefix. */ + char drive[8] = "\\\\.\\A:"; + char *driveletter = drive + 4; + DWORD drives = GetLogicalDrives(); + DWORD mask = 1; + /* Loop over all mounted volumes. */ + while (mask) { + if (mask & drives) { + char device[MAX_PATH*2]; + HANDLE volfile; + + if (QueryDosDeviceA(driveletter, device, MAX_PATH*2)) { + volfile = CreateFileA(device, FILE_READ_DATA, FILE_SHARE_READ, + NULL, OPEN_EXISTING, 0, NULL); + if (volfile != INVALID_HANDLE_VALUE) { + CloseHandle(volfile); + } + } + + /* Flush the drive. */ + volfile = CreateFileA(drive, FILE_READ_DATA, FILE_SHARE_READ, + NULL, OPEN_EXISTING, 0, NULL); + if (volfile != INVALID_HANDLE_VALUE) { + CloseHandle(volfile); + } + } + *driveletter++; + mask = mask << 1; + } +} +#define HAVE_SYNC +#endif + +#ifdef HAVE_SYNC +/*! @decl void sync() + *! + *! Flush operating system disk buffers to permanent storage. + *! + *! @note + *! On some operating systems this may require + *! administrative privileges. + */ +void f_sync(INT32 args) +{ + pop_n_elems(args); + THREADS_ALLOW_UID() + sync(); + THREADS_DISALLOW_UID(); +} +#endif + #ifdef HAVE_INITGROUPS /*! @decl void initgroups(string name, int base_gid) *! @@ -3261,6 +3319,10 @@ PIKE_MODULE_INIT 0, OPT_SIDE_EFFECT); #endif +#ifdef HAVE_SYNC + ADD_FUNCTION2("sync", f_sync, tFunc(tNone, tVoid), 0, OPT_SIDE_EFFECT); +#endif + #ifdef HAVE_INITGROUPS /* function(string, int:void) */ -- GitLab