packages feed

unix-compat 0.2.2.1 → 0.3

raw patch · 13 files changed

+586/−327 lines, 13 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ System.PosixCompat.Temp: mkstemp :: String -> IO (FilePath, Handle)

Files

LICENSE view
@@ -1,4 +1,7 @@-Copyright (c) 2007, Bjorn Bringert+Copyright (c) 2007-2008, Björn Bringert+Copyright (c) 2007-2009, Duncan Coutts+Copyright (c) 2010-2011, Jacob Stanley+Copyright (c)      2011, Bryan O'Sullivan All rights reserved.  Redistribution and use in source and binary forms, with or without 
cbits/HsUname.c view
@@ -105,7 +105,7 @@ # define VER_SUITE_WH_SERVER 0x00008000 #endif -int HsOSDisplayString(char *pszOS, size_t BUFSIZE)+int unixcompat_os_display_string(char *pszOS, size_t BUFSIZE) {     OSVERSIONINFOEX osvi;     SYSTEM_INFO si;@@ -121,213 +121,192 @@     bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO*) &osvi);      if (bOsVersionInfoEx == 0)-	return FALSE;+        return FALSE;      // Call GetNativeSystemInfo if supported or GetSystemInfo otherwise.      pGNSI = (PGNSI) GetProcAddress(-	GetModuleHandle(TEXT("kernel32.dll")), -	"GetNativeSystemInfo");-    if(NULL != pGNSI)-	pGNSI(&si);-    else GetSystemInfo(&si);--    if ( VER_PLATFORM_WIN32_NT==osvi.dwPlatformId && -	 osvi.dwMajorVersion > 4 )-    {-	StringCchCopy(pszOS, BUFSIZE, TEXT("Microsoft "));+        GetModuleHandle(TEXT("kernel32.dll")),+        "GetNativeSystemInfo");+    if (NULL != pGNSI)+        pGNSI(&si);+    else+        GetSystemInfo(&si); -	// Test for the specific product.+    if (VER_PLATFORM_WIN32_NT == osvi.dwPlatformId && osvi.dwMajorVersion > 4) {+        StringCchCopy(pszOS, BUFSIZE, TEXT("Microsoft ")); -	if ( osvi.dwMajorVersion == 6 )-	{-	    if( osvi.dwMinorVersion == 0 )-	    {-		if( osvi.wProductType == VER_NT_WORKSTATION )-		    StringCchCat(pszOS, BUFSIZE, TEXT("Windows Vista "));-		else StringCchCat(pszOS, BUFSIZE, TEXT("Windows Server 2008 " ));-	    }+        // Test for the specific product.+        if (osvi.dwMajorVersion == 6) {+            if(osvi.dwMinorVersion == 0) {+                if(osvi.wProductType == VER_NT_WORKSTATION)+                    StringCchCat(pszOS, BUFSIZE, TEXT("Windows Vista "));+                else+                    StringCchCat(pszOS, BUFSIZE, TEXT("Windows Server 2008 "));+            } -	    if ( osvi.dwMinorVersion == 1 )-	    {-		if( osvi.wProductType == VER_NT_WORKSTATION )-		    StringCchCat(pszOS, BUFSIZE, TEXT("Windows 7 "));-		else StringCchCat(pszOS, BUFSIZE, TEXT("Windows Server 2008 R2 " ));-	    }-         -	    pGPI = (PGPI) GetProcAddress(-		GetModuleHandle(TEXT("kernel32.dll")), -		"GetProductInfo");+            if (osvi.dwMinorVersion == 1) {+                if (osvi.wProductType == VER_NT_WORKSTATION)+                    StringCchCat(pszOS, BUFSIZE, TEXT("Windows 7 "));+                else+                    StringCchCat(pszOS, BUFSIZE, TEXT("Windows Server 2008 R2 "));+            } -	    pGPI( osvi.dwMajorVersion, osvi.dwMinorVersion, 0, 0, &dwType);+            pGPI = (PGPI) GetProcAddress(+                GetModuleHandle(TEXT("kernel32.dll")),+                "GetProductInfo"); -	    switch( dwType )-	    {-            case PRODUCT_ULTIMATE:-		StringCchCat(pszOS, BUFSIZE, TEXT("Ultimate Edition" ));-		break;-            case PRODUCT_PROFESSIONAL:-		StringCchCat(pszOS, BUFSIZE, TEXT("Professional" ));-		break;-            case PRODUCT_HOME_PREMIUM:-		StringCchCat(pszOS, BUFSIZE, TEXT("Home Premium Edition" ));-		break;-            case PRODUCT_HOME_BASIC:-		StringCchCat(pszOS, BUFSIZE, TEXT("Home Basic Edition" ));-		break;-            case PRODUCT_ENTERPRISE:-		StringCchCat(pszOS, BUFSIZE, TEXT("Enterprise Edition" ));-		break;-            case PRODUCT_BUSINESS:-		StringCchCat(pszOS, BUFSIZE, TEXT("Business Edition" ));-		break;-            case PRODUCT_STARTER:-		StringCchCat(pszOS, BUFSIZE, TEXT("Starter Edition" ));-		break;-            case PRODUCT_CLUSTER_SERVER:-		StringCchCat(pszOS, BUFSIZE, TEXT("Cluster Server Edition" ));-		break;-            case PRODUCT_DATACENTER_SERVER:-		StringCchCat(pszOS, BUFSIZE, TEXT("Datacenter Edition" ));-		break;-            case PRODUCT_DATACENTER_SERVER_CORE:-		StringCchCat(pszOS, BUFSIZE, TEXT("Datacenter Edition (core installation)" ));-		break;-            case PRODUCT_ENTERPRISE_SERVER:-		StringCchCat(pszOS, BUFSIZE, TEXT("Enterprise Edition" ));-		break;-            case PRODUCT_ENTERPRISE_SERVER_CORE:-		StringCchCat(pszOS, BUFSIZE, TEXT("Enterprise Edition (core installation)" ));-		break;-            case PRODUCT_ENTERPRISE_SERVER_IA64:-		StringCchCat(pszOS, BUFSIZE, TEXT("Enterprise Edition for Itanium-based Systems" ));-		break;-            case PRODUCT_SMALLBUSINESS_SERVER:-		StringCchCat(pszOS, BUFSIZE, TEXT("Small Business Server" ));-		break;-            case PRODUCT_SMALLBUSINESS_SERVER_PREMIUM:-		StringCchCat(pszOS, BUFSIZE, TEXT("Small Business Server Premium Edition" ));-		break;-            case PRODUCT_STANDARD_SERVER:-		StringCchCat(pszOS, BUFSIZE, TEXT("Standard Edition" ));-		break;-            case PRODUCT_STANDARD_SERVER_CORE:-		StringCchCat(pszOS, BUFSIZE, TEXT("Standard Edition (core installation)" ));-		break;-            case PRODUCT_WEB_SERVER:-		StringCchCat(pszOS, BUFSIZE, TEXT("Web Server Edition" ));-		break;-	    }-	}+            pGPI(osvi.dwMajorVersion, osvi.dwMinorVersion, 0, 0, &dwType); -	if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2 )-	{-	    if( GetSystemMetrics(SM_SERVERR2) )-		StringCchCat(pszOS, BUFSIZE, TEXT( "Windows Server 2003 R2, "));-	    else if ( osvi.wSuiteMask & VER_SUITE_STORAGE_SERVER )-		StringCchCat(pszOS, BUFSIZE, TEXT( "Windows Storage Server 2003"));-	    else if ( osvi.wSuiteMask & VER_SUITE_WH_SERVER )-		StringCchCat(pszOS, BUFSIZE, TEXT( "Windows Home Server"));-	    else if( osvi.wProductType == VER_NT_WORKSTATION &&-		     si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64)-	    {-		StringCchCat(pszOS, BUFSIZE, TEXT( "Windows XP Professional x64 Edition"));-	    }-	    else StringCchCat(pszOS, BUFSIZE, TEXT("Windows Server 2003, "));+            switch (dwType) {+                case PRODUCT_ULTIMATE:+                    StringCchCat(pszOS, BUFSIZE, TEXT("Ultimate Edition"));+                    break;+                case PRODUCT_PROFESSIONAL:+                    StringCchCat(pszOS, BUFSIZE, TEXT("Professional"));+                    break;+                case PRODUCT_HOME_PREMIUM:+                    StringCchCat(pszOS, BUFSIZE, TEXT("Home Premium Edition"));+                    break;+                case PRODUCT_HOME_BASIC:+                    StringCchCat(pszOS, BUFSIZE, TEXT("Home Basic Edition"));+                    break;+                case PRODUCT_ENTERPRISE:+                    StringCchCat(pszOS, BUFSIZE, TEXT("Enterprise Edition"));+                    break;+                case PRODUCT_BUSINESS:+                    StringCchCat(pszOS, BUFSIZE, TEXT("Business Edition"));+                    break;+                case PRODUCT_STARTER:+                    StringCchCat(pszOS, BUFSIZE, TEXT("Starter Edition"));+                    break;+                case PRODUCT_CLUSTER_SERVER:+                    StringCchCat(pszOS, BUFSIZE, TEXT("Cluster Server Edition"));+                    break;+                case PRODUCT_DATACENTER_SERVER:+                    StringCchCat(pszOS, BUFSIZE, TEXT("Datacenter Edition"));+                    break;+                case PRODUCT_DATACENTER_SERVER_CORE:+                    StringCchCat(pszOS, BUFSIZE, TEXT("Datacenter Edition (core installation)"));+                    break;+                case PRODUCT_ENTERPRISE_SERVER:+                    StringCchCat(pszOS, BUFSIZE, TEXT("Enterprise Edition"));+                    break;+                case PRODUCT_ENTERPRISE_SERVER_CORE:+                    StringCchCat(pszOS, BUFSIZE, TEXT("Enterprise Edition (core installation)"));+                    break;+                case PRODUCT_ENTERPRISE_SERVER_IA64:+                    StringCchCat(pszOS, BUFSIZE, TEXT("Enterprise Edition for Itanium-based Systems"));+                    break;+                case PRODUCT_SMALLBUSINESS_SERVER:+                    StringCchCat(pszOS, BUFSIZE, TEXT("Small Business Server"));+                    break;+                case PRODUCT_SMALLBUSINESS_SERVER_PREMIUM:+                    StringCchCat(pszOS, BUFSIZE, TEXT("Small Business Server Premium Edition"));+                    break;+                case PRODUCT_STANDARD_SERVER:+                    StringCchCat(pszOS, BUFSIZE, TEXT("Standard Edition"));+                    break;+                case PRODUCT_STANDARD_SERVER_CORE:+                    StringCchCat(pszOS, BUFSIZE, TEXT("Standard Edition (core installation)"));+                    break;+                case PRODUCT_WEB_SERVER:+                    StringCchCat(pszOS, BUFSIZE, TEXT("Web Server Edition"));+                    break;+            }+        } -	    // Test for the server type.-	    if ( osvi.wProductType != VER_NT_WORKSTATION )-	    {-		if ( si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_IA64 )-		{-		    if( osvi.wSuiteMask & VER_SUITE_DATACENTER )-			StringCchCat(pszOS, BUFSIZE, TEXT( "Datacenter Edition for Itanium-based Systems" ));-		    else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )-			StringCchCat(pszOS, BUFSIZE, TEXT( "Enterprise Edition for Itanium-based Systems" ));-		}+        if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2) {+            if (GetSystemMetrics(SM_SERVERR2))+                StringCchCat(pszOS, BUFSIZE, TEXT("Windows Server 2003 R2, "));+            else if (osvi.wSuiteMask & VER_SUITE_STORAGE_SERVER)+                StringCchCat(pszOS, BUFSIZE, TEXT("Windows Storage Server 2003"));+            else if (osvi.wSuiteMask & VER_SUITE_WH_SERVER)+                StringCchCat(pszOS, BUFSIZE, TEXT("Windows Home Server"));+            else if (osvi.wProductType == VER_NT_WORKSTATION &&+                     si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)+                StringCchCat(pszOS, BUFSIZE, TEXT("Windows XP Professional x64 Edition"));+            else+                StringCchCat(pszOS, BUFSIZE, TEXT("Windows Server 2003, ")); -		else if ( si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64 )-		{-		    if( osvi.wSuiteMask & VER_SUITE_DATACENTER )-			StringCchCat(pszOS, BUFSIZE, TEXT( "Datacenter x64 Edition" ));-		    else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )-			StringCchCat(pszOS, BUFSIZE, TEXT( "Enterprise x64 Edition" ));-		    else StringCchCat(pszOS, BUFSIZE, TEXT( "Standard x64 Edition" ));-		}+            // Test for the server type. -		else-		{-		    if ( osvi.wSuiteMask & VER_SUITE_COMPUTE_SERVER )-			StringCchCat(pszOS, BUFSIZE, TEXT( "Compute Cluster Edition" ));-		    else if( osvi.wSuiteMask & VER_SUITE_DATACENTER )-			StringCchCat(pszOS, BUFSIZE, TEXT( "Datacenter Edition" ));-		    else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )-			StringCchCat(pszOS, BUFSIZE, TEXT( "Enterprise Edition" ));-		    else if ( osvi.wSuiteMask & VER_SUITE_BLADE )-			StringCchCat(pszOS, BUFSIZE, TEXT( "Web Edition" ));-		    else StringCchCat(pszOS, BUFSIZE, TEXT( "Standard Edition" ));-		}-	    }-	}+            if (osvi.wProductType != VER_NT_WORKSTATION) {+                if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64) {+                    if(osvi.wSuiteMask & VER_SUITE_DATACENTER)+                        StringCchCat(pszOS, BUFSIZE, TEXT("Datacenter Edition for Itanium-based Systems"));+                    else if(osvi.wSuiteMask & VER_SUITE_ENTERPRISE)+                        StringCchCat(pszOS, BUFSIZE, TEXT("Enterprise Edition for Itanium-based Systems"));+                } else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) {+                    if(osvi.wSuiteMask & VER_SUITE_DATACENTER)+                        StringCchCat(pszOS, BUFSIZE, TEXT("Datacenter x64 Edition"));+                    else if(osvi.wSuiteMask & VER_SUITE_ENTERPRISE)+                        StringCchCat(pszOS, BUFSIZE, TEXT("Enterprise x64 Edition"));+                    else StringCchCat(pszOS, BUFSIZE, TEXT("Standard x64 Edition"));+                } else {+                    if (osvi.wSuiteMask & VER_SUITE_COMPUTE_SERVER)+                        StringCchCat(pszOS, BUFSIZE, TEXT("Compute Cluster Edition"));+                    else if(osvi.wSuiteMask & VER_SUITE_DATACENTER)+                        StringCchCat(pszOS, BUFSIZE, TEXT("Datacenter Edition"));+                    else if(osvi.wSuiteMask & VER_SUITE_ENTERPRISE)+                        StringCchCat(pszOS, BUFSIZE, TEXT("Enterprise Edition"));+                    else if (osvi.wSuiteMask & VER_SUITE_BLADE)+                        StringCchCat(pszOS, BUFSIZE, TEXT("Web Edition"));+                    else StringCchCat(pszOS, BUFSIZE, TEXT("Standard Edition"));+                }+            }+        } -	if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1 )-	{-	    StringCchCat(pszOS, BUFSIZE, TEXT("Windows XP "));-	    if( osvi.wSuiteMask & VER_SUITE_PERSONAL )-		StringCchCat(pszOS, BUFSIZE, TEXT( "Home Edition" ));-	    else StringCchCat(pszOS, BUFSIZE, TEXT( "Professional" ));-	}+        if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1) {+            StringCchCat(pszOS, BUFSIZE, TEXT("Windows XP ")); -	if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0 )-	{-	    StringCchCat(pszOS, BUFSIZE, TEXT("Windows 2000 "));+            if (osvi.wSuiteMask & VER_SUITE_PERSONAL)+                StringCchCat(pszOS, BUFSIZE, TEXT("Home Edition"));+            else+                StringCchCat(pszOS, BUFSIZE, TEXT("Professional"));+        } -	    if ( osvi.wProductType == VER_NT_WORKSTATION )-	    {-		StringCchCat(pszOS, BUFSIZE, TEXT( "Professional" ));-	    }-	    else -	    {-		if( osvi.wSuiteMask & VER_SUITE_DATACENTER )-		    StringCchCat(pszOS, BUFSIZE, TEXT( "Datacenter Server" ));-		else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )-		    StringCchCat(pszOS, BUFSIZE, TEXT( "Advanced Server" ));-		else StringCchCat(pszOS, BUFSIZE, TEXT( "Server" ));-	    }-	}+        if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0) {+            StringCchCat(pszOS, BUFSIZE, TEXT("Windows 2000 ")); -	// Include service pack (if any) and build number.+            if (osvi.wProductType == VER_NT_WORKSTATION) {+                StringCchCat(pszOS, BUFSIZE, TEXT("Professional"));+            } else {+                if(osvi.wSuiteMask & VER_SUITE_DATACENTER)+                    StringCchCat(pszOS, BUFSIZE, TEXT("Datacenter Server"));+                else if(osvi.wSuiteMask & VER_SUITE_ENTERPRISE)+                    StringCchCat(pszOS, BUFSIZE, TEXT("Advanced Server"));+                else+                    StringCchCat(pszOS, BUFSIZE, TEXT("Server"));+            }+        } -	if( _tcslen(osvi.szCSDVersion) > 0 )-	{-	    StringCchCat(pszOS, BUFSIZE, TEXT(" ") );-	    StringCchCat(pszOS, BUFSIZE, osvi.szCSDVersion);-	}+        // Include service pack (if any) and build number. -	char buf[80];+        if(_tcslen(osvi.szCSDVersion) > 0) {+            StringCchCat(pszOS, BUFSIZE, TEXT(" "));+            StringCchCat(pszOS, BUFSIZE, osvi.szCSDVersion);+        } -	StringCchPrintf( buf, 80, TEXT(" (build %d)"), osvi.dwBuildNumber);-	StringCchCat(pszOS, BUFSIZE, buf);+        char buf[80];+        StringCchPrintf(buf, 80, TEXT(" (build %d)"), osvi.dwBuildNumber);+        StringCchCat(pszOS, BUFSIZE, buf); -	if ( osvi.dwMajorVersion >= 6 )-	{-	    if ( si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64 )-		StringCchCat(pszOS, BUFSIZE, TEXT( ", 64-bit" ));-	    else if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_INTEL )-		StringCchCat(pszOS, BUFSIZE, TEXT(", 32-bit"));-	}-      -	return TRUE;-    }+        if (osvi.dwMajorVersion >= 6) {+            if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)+                StringCchCat(pszOS, BUFSIZE, TEXT(", 64-bit"));+            else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)+                StringCchCat(pszOS, BUFSIZE, TEXT(", 32-bit"));+        } -    else-    {  -	//printf( "This sample does not support this version of Windows.\n");-	return FALSE;+        return TRUE;+    } else {+        // This sample does not support this version of Windows.+        return FALSE;     } } -int HsOSVersionString(char *ptr, size_t bufsize)+int unixcompat_os_version_string(char *ptr, size_t bufsize) {     OSVERSIONINFOEX osvi;     BOOL bOsVersionInfoEx;@@ -336,44 +315,44 @@     ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));     osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);     bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO*) &osvi);-    +     if (bOsVersionInfoEx == 0)-	return FALSE;+        return FALSE;      if (strncmp(osvi.szCSDVersion, "Service Pack ", 13) == 0)-	szServicePack = "0";+        szServicePack = "0";     else-	szServicePack = osvi.szCSDVersion + 13;+        szServicePack = osvi.szCSDVersion + 13;      StringCchPrintf(ptr, bufsize, "%ld.%ld.%s.%ld",-		    osvi.dwMajorVersion, osvi.dwMinorVersion, szServicePack,-		    osvi.dwBuildNumber);+                    osvi.dwMajorVersion, osvi.dwMinorVersion, szServicePack,+                    osvi.dwBuildNumber);      return TRUE; } -int HsOSArchString(char *ptr, size_t bufsize)+int unixcompat_os_arch_string(char *ptr, size_t bufsize) {     SYSTEM_INFO sysInfo;      GetSystemInfo(&sysInfo);      switch (sysInfo.wProcessorArchitecture) {-    case PROCESSOR_ARCHITECTURE_INTEL:-	StringCchCopy(ptr, bufsize, "i386");-	break;-    case PROCESSOR_ARCHITECTURE_AMD64:-	StringCchCopy(ptr, bufsize, "x86_64");-	break;-    default:-	StringCchCopy(ptr, bufsize, "unknown");-	break;+        case PROCESSOR_ARCHITECTURE_INTEL:+            StringCchCopy(ptr, bufsize, "i386");+            break;+        case PROCESSOR_ARCHITECTURE_AMD64:+            StringCchCopy(ptr, bufsize, "x86_64");+            break;+        default:+            StringCchCopy(ptr, bufsize, "unknown");+            break;     }      return TRUE; } -int HsOSNodeName(char *ptr, size_t bufsize)+int unixcompat_os_node_name(char *ptr, size_t bufsize) {     DWORD sLength; 
cbits/HsUnixCompat.c view
@@ -4,15 +4,17 @@ #include <sys/mkdev.h> #endif -unsigned int unix_major(dev_t dev) {-  return major(dev);+unsigned int unix_major(dev_t dev)+{+    return major(dev); } -unsigned int unix_minor(dev_t dev) {-  return minor(dev);+unsigned int unix_minor(dev_t dev)+{+    return minor(dev); } -dev_t unix_makedev(unsigned int maj, unsigned int min) {-  return makedev(maj, min);+dev_t unix_makedev(unsigned int maj, unsigned int min)+{+    return makedev(maj, min); }-
+ cbits/mktemp.c view
@@ -0,0 +1,172 @@+/*+ * Modified version of 'mktemp.c' from FreeBSD+ * http://www.freebsd.org/cgi/cvsweb.cgi/src/lib/libc/stdio/mktemp.c+ *     ?rev=1.29.2.2.2.1;content-type=text%2Fplain+ */++/*+ * Copyright (c) 1987, 1993+ *	The Regents of the University of California.  All rights reserved.+ *+ * Redistribution and use in source and binary forms, with or without+ * modification, are permitted provided that the following conditions+ * are met:+ * 1. Redistributions of source code must retain the above copyright+ *    notice, this list of conditions and the following disclaimer.+ * 2. Redistributions in binary form must reproduce the above copyright+ *    notice, this list of conditions and the following disclaimer in the+ *    documentation and/or other materials provided with the distribution.+ * 4. Neither the name of the University nor the names of its contributors+ *    may be used to endorse or promote products derived from this software+ *    without specific prior written permission.+ *+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF+ * SUCH DAMAGE.+ */++#include <sys/param.h>+#include <sys/stat.h>+#include <fcntl.h>+#include <errno.h>+#include <stdlib.h>+#include <string.h>+#include <unistd.h>+#include <windows.h>+#include <wincrypt.h>++static int random(uint32_t *);+static int _gettemp(char *, int *);++static const unsigned char padchar[] =+"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";++int unixcompat_mkstemp(char *path)+{+	int fd;++	if (_gettemp(path, &fd))+        return fd;++    return -1;+}++static int _gettemp(char *path, int *doopen)+{+	char *start, *trv, *suffp, *carryp;+	char *pad;+	struct stat sbuf;+	int rval;+	uint32_t randidx, randval;+	char carrybuf[MAXPATHLEN];++	for (trv = path; *trv != '\0'; ++trv)+		;+	if (trv - path >= MAXPATHLEN) {+		errno = ENAMETOOLONG;+		return (0);+	}+	suffp = trv;+	--trv;+	if (trv < path || NULL != strchr(suffp, '/')) {+		errno = EINVAL;+		return (0);+	}++	/* Fill space with random characters */+	while (trv >= path && *trv == 'X') {+        if (!random(&randval)) {+            /* this should never happen */+            errno = EIO;+            return 0;+        }+		randidx = randval % (sizeof(padchar) - 1);+		*trv-- = padchar[randidx];+	}+	start = trv + 1;++	/* save first combination of random characters */+	memcpy(carrybuf, start, suffp - start);++	/*+	 * check the target directory.+	 */+	if (doopen != NULL) {+		for (; trv > path; --trv) {+			if (*trv == '/') {+				*trv = '\0';+				rval = stat(path, &sbuf);+				*trv = '/';+				if (rval != 0)+					return (0);+				if (!S_ISDIR(sbuf.st_mode)) {+					errno = ENOTDIR;+					return (0);+				}+				break;+			}+		}+	}++	for (;;) {+		if (doopen) {+			if ((*doopen =+			    _open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0)+				return (1);+			if (errno != EEXIST)+				return (0);+		} else if (stat(path, &sbuf))+			return (errno == ENOENT);++		/* If we have a collision, cycle through the space of filenames */+		for (trv = start, carryp = carrybuf;;) {+			/* have we tried all possible permutations? */+			if (trv == suffp)+				return (0); /* yes - exit with EEXIST */+			pad = strchr(padchar, *trv);+			if (pad == NULL) {+				/* this should never happen */+				errno = EIO;+				return (0);+			}+			/* increment character */+			*trv = (*++pad == '\0') ? padchar[0] : *pad;+			/* carry to next position? */+			if (*trv == *carryp) {+				/* increment position and loop */+				++trv;+				++carryp;+			} else {+				/* try with new name */+				break;+			}+		}+	}+	/*NOTREACHED*/+}++static int random(uint32_t *value)+{+    /* This handle is never released. Windows will clean up when the process+     * exits. Python takes this approach when emulating /dev/urandom, and if+     * it's good enough for them, then it's good enough for us. */+    static HCRYPTPROV context = 0;++    if (context == 0)+        if (!CryptAcquireContext(+                &context, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))+            return 0;++    if (!CryptGenRandom(context, sizeof *value, (BYTE *)value))+        return 0;++    return 1;+}
src/System/PosixCompat.hs view
@@ -1,27 +1,33 @@+{-# LANGUAGE CPP #-}+ {-| The @unix-compat@ package provides portable implementations of parts of the @unix@ package. On POSIX system it re-exports operations from the @unix@ package, on other platforms it emulates the operations as far as possible. -} module System.PosixCompat (-    module System.PosixCompat.Files,-    module System.PosixCompat.Time,-    module System.PosixCompat.Types,-    module System.PosixCompat.User,-    usingPortableImpl-  ) where+      module System.PosixCompat.Files+    , module System.PosixCompat.Temp+    , module System.PosixCompat.Time+    , module System.PosixCompat.Types+    , module System.PosixCompat.Unistd+    , module System.PosixCompat.User+    , usingPortableImpl+    ) where  import System.PosixCompat.Files+import System.PosixCompat.Temp import System.PosixCompat.Time import System.PosixCompat.Types+import System.PosixCompat.Unistd import System.PosixCompat.User  -- | 'True' if unix-compat is using its portable implementation, --   or 'False' if the unix package is simply being re-exported. usingPortableImpl :: Bool-#ifdef UNIX_IMPL-usingPortableImpl = False-#else+#ifdef mingw32_HOST_OS usingPortableImpl = True+#else+usingPortableImpl = False #endif 
src/System/PosixCompat/Extensions.hsc view
@@ -1,12 +1,18 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE ForeignFunctionInterface #-}+ -- | This module provides some functions not present in the unix package. module System.PosixCompat.Extensions (-         -- * Device IDs.-         CMajor, CMinor,-         deviceMajor, deviceMinor, makeDeviceID-   ) where+    -- * Device IDs.+      CMajor+    , CMinor+    , deviceMajor+    , deviceMinor+    , makeDeviceID+    ) where  -#ifdef UNIX_IMPL+#ifndef mingw32_HOST_OS #include "HsUnixCompat.h" #endif @@ -21,33 +27,32 @@ -- -- The portable implementation always returns @0@. deviceMajor :: DeviceID -> CMajor-#ifdef UNIX_IMPL+#ifdef mingw32_HOST_OS+deviceMajor _ = 0+#else deviceMajor dev = unix_major dev  foreign import ccall unsafe "unix_major" unix_major :: CDev -> CUInt-#else-deviceMajor _ = 0 #endif  -- | Gets the minor number from a 'DeviceID' for a device file. -- -- The portable implementation always returns @0@. deviceMinor :: DeviceID -> CMinor-#ifdef UNIX_IMPL+#ifdef mingw32_HOST_OS+deviceMinor _ = 0+#else deviceMinor dev = unix_minor dev  foreign import ccall unsafe "unix_minor" unix_minor :: CDev -> CUInt-#else-deviceMinor _ = 0 #endif  -- | Creates a 'DeviceID' for a device file given a major and minor number. makeDeviceID :: CMajor -> CMinor -> DeviceID-#ifdef UNIX_IMPL+#ifdef mingw32_HOST_OS+makeDeviceID _ _ = 0+#else makeDeviceID ma mi = unix_makedev ma mi  foreign import ccall unsafe "unix_makedev" unix_makedev :: CUInt -> CUInt -> CDev-#else-makeDeviceID _ _ = 0 #endif-
src/System/PosixCompat/Files.hsc view
@@ -1,3 +1,5 @@+{-# LANGUAGE CPP #-}+ {-| This module makes the operations exported by @System.Posix.Files@ available on all platforms. On POSIX systems it re-exports operations from@@ -10,59 +12,96 @@ module System.PosixCompat.Files (     -- * File modes     -- FileMode exported by System.Posix.Types-    unionFileModes, intersectFileModes,-    nullFileMode,-    ownerReadMode, ownerWriteMode, ownerExecuteMode, ownerModes,-    groupReadMode, groupWriteMode, groupExecuteMode, groupModes,-    otherReadMode, otherWriteMode, otherExecuteMode, otherModes,-    setUserIDMode, setGroupIDMode,-    stdFileMode,   accessModes,+      unionFileModes+    , intersectFileModes+    , nullFileMode+    , ownerReadMode+    , ownerWriteMode+    , ownerExecuteMode+    , ownerModes+    , groupReadMode+    , groupWriteMode+    , groupExecuteMode+    , groupModes+    , otherReadMode+    , otherWriteMode+    , otherExecuteMode+    , otherModes+    , setUserIDMode+    , setGroupIDMode+    , stdFileMode+    , accessModes      -- ** Setting file modes-    setFileMode, setFdMode, setFileCreationMask,+    , setFileMode+    , setFdMode+    , setFileCreationMask      -- ** Checking file existence and permissions-    fileAccess, fileExist,+    , fileAccess+    , fileExist      -- * File status-    FileStatus,+    , FileStatus     -- ** Obtaining file status-    getFileStatus, getFdStatus, getSymbolicLinkStatus,+    , getFileStatus+    , getFdStatus+    , getSymbolicLinkStatus     -- ** Querying file status-    deviceID, fileID, fileMode, linkCount, fileOwner, fileGroup,-    specialDeviceID, fileSize, accessTime, modificationTime,-    statusChangeTime,-    isBlockDevice, isCharacterDevice, isNamedPipe, isRegularFile,-    isDirectory, isSymbolicLink, isSocket,+    , deviceID+    , fileID+    , fileMode+    , linkCount+    , fileOwner+    , fileGroup+    , specialDeviceID+    , fileSize+    , accessTime+    , modificationTime+    , statusChangeTime+    , isBlockDevice+    , isCharacterDevice+    , isNamedPipe+    , isRegularFile+    , isDirectory+    , isSymbolicLink+    , isSocket      -- * Creation-    createNamedPipe,-    createDevice,+    , createNamedPipe+    , createDevice      -- * Hard links-    createLink, removeLink,+    , createLink+    , removeLink      -- * Symbolic links-    createSymbolicLink, readSymbolicLink,+    , createSymbolicLink+    , readSymbolicLink      -- * Renaming files-    rename,+    , rename      -- * Changing file ownership-    setOwnerAndGroup,  setFdOwnerAndGroup,-    setSymbolicLinkOwnerAndGroup,+    , setOwnerAndGroup+    , setFdOwnerAndGroup+    , setSymbolicLinkOwnerAndGroup      -- * Changing file timestamps-    setFileTimes, touchFile,+    , setFileTimes+    , touchFile      -- * Setting file sizes-    setFileSize, setFdSize,+    , setFileSize+    , setFdSize      -- * Find system-specific limits for a file-    PathVar(..), getPathVar, getFdPathVar,- ) where+    , PathVar(..)+    , getPathVar+    , getFdPathVar+    ) where -#ifdef UNIX_IMPL+#ifndef mingw32_HOST_OS  #include "HsUnixCompat.h" 
+ src/System/PosixCompat/Temp.hs view
@@ -0,0 +1,53 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE ForeignFunctionInterface #-}++{-|+This module makes the operations exported by @System.Posix.Temp@+available on all platforms. On POSIX systems it re-exports operations from+@System.Posix.Temp@, on other platforms it emulates the operations as far+as possible.+-}+module System.PosixCompat.Temp (+      mkstemp+    ) where++#ifndef mingw32_HOST_OS+-- Re-export unix package++import System.Posix.Temp++#elif defined(__GLASGOW_HASKELL__)+-- Windows w/ GHC, we have fdToHandle so we+-- can use our own implementation of mkstemp.++import System.IO (Handle)+import Foreign.C (CInt, CString, withCString, peekCString, throwErrnoIfMinus1)+import GHC.IO.Handle.FD (fdToHandle)++-- | 'mkstemp' - make a unique filename and open it for+-- reading\/writing.+-- The returned 'FilePath' is the (possibly relative) path of+-- the created file, which is padded with 6 random characters.+mkstemp :: String -> IO (FilePath, Handle)+mkstemp template = do+  withCString template $ \ ptr -> do+    fd <- throwErrnoIfMinus1 "mkstemp" (c_mkstemp ptr)+    name <- peekCString ptr+    h <- fdToHandle (fromIntegral fd)+    return (name, h)++foreign import ccall unsafe "unixcompat_mkstemp"+    c_mkstemp :: CString -> IO CInt++#else+-- Windows w/o GHC, we don't have fdToHandle :(++import System.IO (Handle)+import System.IO.Error (mkIOError, illegalOperationErrorType)++mkstemp :: String -> IO (FilePath, Handle)+mkstemp _ = ioError $ mkIOError illegalOperationErrorType x Nothing Nothing+  where+    x = "System.PosixCompat.Temp.mkstemp: not supported"++#endif
src/System/PosixCompat/Time.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE CPP #-}+ {-| This module makes the operations exported by @System.Posix.Time@ available on all platforms. On POSIX systems it re-exports operations from@@ -5,10 +7,10 @@ as possible. -} module System.PosixCompat.Time (-    epochTime,-  ) where+      epochTime+    ) where -#ifdef UNIX_IMPL+#ifndef mingw32_HOST_OS  import System.Posix.Time 
src/System/PosixCompat/Types.hs view
@@ -1,3 +1,6 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+ {-| This module re-exports the types from @System.Posix.Types@ on all platforms. @@ -5,15 +8,17 @@ redefined by this module. -} module System.PosixCompat.Types (-    module System.Posix.Types,-#ifdef MISSING_POSIX_TYPES-    UserID, GroupID, LinkCount+      module System.Posix.Types+#ifdef mingw32_HOST_OS+    , UserID+    , GroupID+    , LinkCount #endif-  ) where+    ) where  import System.Posix.Types -#ifdef MISSING_POSIX_TYPES+#ifdef mingw32_HOST_OS  import Data.Word (Word32) @@ -36,4 +41,3 @@                                               | (x,s') <- readsPrec i s]  #endif-
src/System/PosixCompat/Unistd.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP #-} {-# LANGUAGE ForeignFunctionInterface #-}  {-|@@ -6,8 +7,7 @@ @System.Posix.Unistd@, on other platforms it emulates the operations as far as possible. -}-module System.PosixCompat.Unistd-    (+module System.PosixCompat.Unistd (     -- * System environment       SystemID(..)     , getSystemID@@ -17,7 +17,7 @@     , nanosleep     ) where -#ifdef UNIX_IMPL+#ifndef mingw32_HOST_OS  import System.Posix.Unistd @@ -40,21 +40,21 @@ getSystemID = do   let bufSize = 256   let call f = allocaArray bufSize $ \buf -> do-	ok <- f buf (fromIntegral bufSize)-	if ok == 1-	  then peekCString buf-	  else return ""-  display <- call c_HsOSDisplayString-  vers <- call c_HsOSVersionString-  arch <- call c_HsOSArchString-  node <- call c_HsOSNodeName+        ok <- f buf (fromIntegral bufSize)+        if ok == 1+          then peekCString buf+          else return ""+  display <- call c_os_display_string+  vers <- call c_os_version_string+  arch <- call c_os_arch_string+  node <- call c_os_node_name   return SystemID {            systemName = "Windows"-	 , nodeName = node-	 , release = display+         , nodeName = node+         , release = display          , version = vers-	 , machine = arch-	 }+         , machine = arch+         }  -- | Sleep for the specified duration (in seconds). Returns the time -- remaining (if the sleep was interrupted by a signal, for example).@@ -86,16 +86,16 @@ nanosleep :: Integer -> IO () nanosleep nsecs = threadDelay (round (fromIntegral nsecs / 1000 :: Double)) -foreign import ccall "HsOSDisplayString" c_HsOSDisplayString-    :: CString -> CSize -> IO CInt+foreign import ccall "unixcompat_os_display_string"+    c_os_display_string :: CString -> CSize -> IO CInt -foreign import ccall "HsOSVersionString" c_HsOSVersionString-    :: CString -> CSize -> IO CInt+foreign import ccall "unixcompat_os_version_string"+    c_os_version_string :: CString -> CSize -> IO CInt -foreign import ccall "HsOSArchString" c_HsOSArchString-    :: CString -> CSize -> IO CInt+foreign import ccall "unixcompat_os_arch_string"+    c_os_arch_string :: CString -> CSize -> IO CInt -foreign import ccall "HsOSNodeName" c_HsOSNodeName-    :: CString -> CSize -> IO CInt+foreign import ccall "unixcompat_os_node_name"+    c_os_node_name :: CString -> CSize -> IO CInt  #endif
src/System/PosixCompat/User.hsc view
@@ -1,3 +1,5 @@+{-# LANGUAGE CPP #-}+ {-| This module makes the operations exported by @System.Posix.User@ available on all platforms. On POSIX systems it re-exports operations from@@ -6,32 +8,32 @@ module System.PosixCompat.User (     -- * User environment     -- ** Querying the user environment-    getRealUserID,-    getRealGroupID,-    getEffectiveUserID,-    getEffectiveGroupID,-    getGroups,-    getLoginName,-    getEffectiveUserName,+      getRealUserID+    , getRealGroupID+    , getEffectiveUserID+    , getEffectiveGroupID+    , getGroups+    , getLoginName+    , getEffectiveUserName      -- *** The group database-    GroupEntry(..),-    getGroupEntryForID,-    getGroupEntryForName,-    getAllGroupEntries,+    , GroupEntry(..)+    , getGroupEntryForID+    , getGroupEntryForName+    , getAllGroupEntries      -- *** The user database-    UserEntry(..),-    getUserEntryForID,-    getUserEntryForName,-    getAllUserEntries,+    , UserEntry(..)+    , getUserEntryForID+    , getUserEntryForName+    , getAllUserEntries      -- ** Modifying the user environment-    setUserID,-    setGroupID-  ) where+    , setUserID+    , setGroupID+    ) where -#ifdef UNIX_IMPL+#ifndef mingw32_HOST_OS  #include "HsUnixCompat.h" 
unix-compat.cabal view
@@ -1,5 +1,5 @@ name:           unix-compat-version:        0.2.2.1+version:        0.3 synopsis:       Portable POSIX-compatibility layer. description:    This package provides portable implementations of parts                 of the unix package. This package re-exports the unix@@ -19,42 +19,34 @@   type:     git   location: git://github.com/jystic/unix-compat.git -Flag portable-  default: False-  description: Force compiling in portable mode, useful for testing.- Library   hs-source-dirs: src+  ghc-options: -Wall+  build-depends: base == 4.*    exposed-modules:     System.PosixCompat     System.PosixCompat.Extensions     System.PosixCompat.Files+    System.PosixCompat.Temp     System.PosixCompat.Time     System.PosixCompat.Types     System.PosixCompat.Unistd     System.PosixCompat.User-  extensions: CPP-  ghc-options: -Wall-  build-depends: base == 4.* -  if flag(portable) || os(windows)+  if os(windows)     build-depends: old-time == 1.0.*-    extensions: GeneralizedNewtypeDeriving+    c-sources:+      cbits/HsUname.c+      cbits/mktemp.c      if impl(ghc < 7)       build-depends: directory == 1.0.*       cpp-options: -DDIRECTORY_1_0     else       build-depends: directory == 1.1.*--    if os(windows)-      cpp-options: -DMISSING_POSIX_TYPES-      c-sources: cbits/HsUname.c   else     build-depends: unix >= 2.4 && < 2.6-    extensions: ForeignFunctionInterface-    cpp-options: -DUNIX_IMPL     include-dirs: include     includes: HsUnixCompat.h     install-includes: HsUnixCompat.h