Revision: 45508
http://brlcad.svn.sourceforge.net/brlcad/?rev=45508&view=rev
Author: brlcad
Date: 2011-07-15 21:31:14 +0000 (Fri, 15 Jul 2011)
Log Message:
-----------
implement fchmod() for Windows. this will likely break the Windows build, but
committing it since the only issue should be minor header and preprocessor
symbolage. in order to implement fchmod on Windows, we rely on chmod() instead
which is available but requires a filename. this is normally not knowable, but
windows provides a roundabout way to get it, so run with it.
Modified Paths:
--------------
brlcad/trunk/src/libbu/fchmod.c
Modified: brlcad/trunk/src/libbu/fchmod.c
===================================================================
--- brlcad/trunk/src/libbu/fchmod.c 2011-07-15 21:28:35 UTC (rev 45507)
+++ brlcad/trunk/src/libbu/fchmod.c 2011-07-15 21:31:14 UTC (rev 45508)
@@ -26,7 +26,16 @@
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
+#include "bio.h"
+#ifndef HAVE_FCHMOD
+/* headers for the GetFileNameFromHandle() function below */
+# include <tchar.h>
+# include <string.h>
+# include <psapi.h>
+# include <strsafe.h>
+#endif
+
#include "bu.h"
@@ -37,6 +46,83 @@
#ifdef HAVE_FCHMOD
extern int fchmod(int, mode_t);
+#else
+
+/* Presumably Windows, pulled from MSDN sample code */
+int
+GetFileNameFromHandle(HANDLE hFile, char filepath[])
+{
+ int bSuccess = 0;
+ TCHAR pszFilename[MAXPATHLEN+1];
+ char filename[MAXPATHLEN+1];
+ HANDLE hFileMap;
+
+ /* Get the file size. */
+ DWORD dwFileSizeHi = 0;
+ DWORD dwFileSizeLo = GetFileSize(hFile, &dwFileSizeHi);
+
+ if (dwFileSizeLo == 0 && dwFileSizeHi == 0) {
+ _tprintf(TEXT("Cannot map a file with a length of zero.\n"));
+ return FALSE;
+ }
+
+ /* Create a file mapping object. */
+ hFileMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 1, NULL);
+
+ if (hFileMap) {
+ /* Create a file mapping to get the file name. */
+ void* pMem = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 1);
+
+ if (pMem) {
+ if (GetMappedFileName (GetCurrentProcess(), pMem, pszFilename,
MAXPATHLEN)) {
+
+ /* Translate path with device name to drive letters. */
+ TCHAR szTemp[BUFSIZE];
+ szTemp[0] = '\0';
+
+ if (GetLogicalDriveStrings(BUFSIZE-1, szTemp)) {
+ TCHAR szName[MAXPATHLEN];
+ TCHAR szDrive[3] = TEXT(" :");
+ int bFound = 0;
+ TCHAR* p = szTemp;
+
+ do {
+ /* Copy the drive letter to the template string */
+ *szDrive = *p;
+
+ /* Look up each device name */
+ if (QueryDosDevice(szDrive, szName, MAXPATHLEN)) {
+ size_t uNameLen = _tcslen(szName);
+
+ if (uNameLen < MAXPATHLEN) {
+ bFound = _tcsnicmp(pszFilename, szName,
uNameLen) == 0;
+
+ if (bFound && *(pszFilename + uNameLen) ==
_T('\\')) {
+ /* Reconstruct pszFilename using szTempFile
*/
+ /* Replace device path with DOS path */
+ TCHAR szTempFile[MAXPATHLEN];
+ StringCchPrintf(szTempFile, MAXPATHLEN,
TEXT("%s%s"), szDrive, pszFilename+uNameLen);
+ StringCchCopyN(pszFilename, MAXPATHLEN+1,
szTempFile, _tcslen(szTempFile));
+ }
+ }
+ }
+
+ /* Go to the next NULL character. */
+ while (*p++);
+ } while (!bFound && *p)
+ ; /* end of string */
+ }
+ }
+ bSuccess = TRUE;
+ UnmapViewOfFile(pMem);
+ }
+
+ CloseHandle(hFileMap);
+ }
+ wcstombs(filename, pszFilename, MAXPATHLEN);
+ bu_strlcpy(filepath, filename, MAXPATHLEN);
+ return(bSuccess);
+}
#endif
@@ -51,11 +137,26 @@
#ifdef HAVE_FCHMOD
return fchmod(fileno(fp), (mode_t)pmode);
#else
- pmode = pmode; /* quellage */
- return -1; /* probably Windows, fchmod unavailable and chmod insecure */
+ /* Presumably Windows, so get dirty. We can call chmod() instead
+ * of fchmod(), but that means we need to know the file name.
+ * This isn't portably knowable, but Windows provides a roundabout
+ * way to figure it out.
+ *
+ * If we were willing to limit ourselves to Windows 2000 or 7+, we
+ * could call GetModuleFileNameEx() but there are reports that
+ * it's rather unreliable.
+ */
+ {
+ const char filepath[MAXPATHLEN+1];
+ int fd = fileno(fp);
+ HANDLE h = (HANDLE)_get_osfhandle(fd);
+ GetFileNameFromHandle(h, &filepath);
+ return chmod(filepath, (mode_t)pmode);
+ }
#endif
}
+
/*
* Local Variables:
* mode: C
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
AppSumo Presents a FREE Video for the SourceForge Community by Eric
Ries, the creator of the Lean Startup Methodology on "Lean Startup
Secrets Revealed." This video shows you how to validate your ideas,
optimize your ideas and identify your business strategy.
http://p.sf.net/sfu/appsumosfdev2dev
_______________________________________________
BRL-CAD Source Commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/brlcad-commits