[polyml] 07/13: Add support for the Hurd by removing all use of MAXPATHLEN
James Clarke
jrtc27-guest at moszumanska.debian.org
Sat Mar 12 20:28:25 UTC 2016
This is an automated email from the git hooks/post-receive script.
jrtc27-guest pushed a commit to branch master
in repository polyml.
commit b90cc5e7aa69c7d871ba69ffe8632d83fba6ac2e
Author: James Clarke <jrtc27 at jrtc27.com>
Date: Fri Mar 11 16:55:22 2016 +0000
Add support for the Hurd by removing all use of MAXPATHLEN
---
debian/changelog | 2 +
debian/patches/maxpathlen.diff | 420 +++++++++++++++++++++++++++++++++++++++++
debian/patches/series | 1 +
3 files changed, 423 insertions(+)
diff --git a/debian/changelog b/debian/changelog
index 408e49a..92d5ffa 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,8 +1,10 @@
polyml (5.6-3) UNRELEASED; urgency=low
+ * Support for the Hurd
* New patches:
- alpha.diff: Add support for alpha
- m68k.diff: Add support for m68k
+ - maxpathlen.diff: Remove all use of MAXPATHLEN
- mips64.diff: Add support for mips64/mips64el
- x32.diff: Add support for x32
diff --git a/debian/patches/maxpathlen.diff b/debian/patches/maxpathlen.diff
new file mode 100644
index 0000000..16e4055
--- /dev/null
+++ b/debian/patches/maxpathlen.diff
@@ -0,0 +1,420 @@
+Description: Remove all use of MAXPATHLEN and its variants
+Author: James Clarke <jrtc27 at jrtc27.com>
+Forwarded: https://github.com/polyml/polyml/pull/33
+---
+This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
+--- a/libpolyml/basicio.cpp
++++ b/libpolyml/basicio.cpp
+@@ -111,10 +111,6 @@
+ #define _tcsdup strdup
+ #endif
+
+-#if(!defined(MAXPATHLEN) && defined(MAX_PATH))
+-#define MAXPATHLEN MAX_PATH
+-#endif
+-
+ #ifndef O_BINARY
+ #define O_BINARY 0 /* Not relevant. */
+ #endif
+@@ -1651,13 +1647,21 @@
+ raise_syscall(taskData, "GetCurrentDirectory failed", -(int)GetLastError());
+ return SAVE(C_string_to_Poly(taskData, buff));
+ #else
+- // This is a bit messy in Unix. getcwd will return an error result if there's
+- // not enough space be we have to iterate to find the size.
+- // Use the fixed size for the moment.
+- TCHAR string_buffer[MAXPATHLEN+1];
+- if (getcwd(string_buffer, MAXPATHLEN+1) == NULL)
++ size_t size = 4096;
++ TempString string_buffer((TCHAR *)malloc(size * sizeof(TCHAR)));
++ if (string_buffer == NULL) raise_syscall(taskData, "Insufficient memory", ENOMEM);
++ TCHAR *cwd;
++ while ((cwd = getcwd(string_buffer, size)) == NULL && errno == ERANGE) {
++ if (size > SIZE_MAX / 2) raise_fail(taskData, "getcwd needs too large a buffer");
++ size *= 2;
++ TCHAR *new_buf = (TCHAR *)realloc(string_buffer, size * sizeof(TCHAR));
++ if (new_buf == NULL) raise_syscall(taskData, "Insufficient memory", ENOMEM);
++ string_buffer = new_buf;
++ }
++
++ if (cwd == NULL)
+ raise_syscall(taskData, "getcwd failed", errno);
+- return SAVE(C_string_to_Poly(taskData, string_buffer));
++ return SAVE(C_string_to_Poly(taskData, cwd));
+ #endif
+ }
+
+@@ -1728,8 +1732,19 @@
+ int nLen;
+ TempString linkName(args->Word());
+ if (linkName == 0) raise_syscall(taskData, "Insufficient memory", ENOMEM);
+- char resBuf[MAXPATHLEN];
+- nLen = readlink(linkName, resBuf, sizeof(resBuf));
++
++ size_t size = 4096;
++ TempString resBuf((TCHAR *)malloc(size * sizeof(TCHAR)));
++ if (resBuf == NULL) raise_syscall(taskData, "Insufficient memory", ENOMEM);
++ // nLen is signed, so cast size to ssize_t to perform signed
++ // comparison, avoiding an infinite loop when nLen is -1.
++ while ((nLen = readlink(linkName, resBuf, size)) >= (ssize_t) size) {
++ size *= 2;
++ if (size > SSIZE_MAX) raise_fail(taskData, "readlink needs too large a buffer");
++ TCHAR *newBuf = (TCHAR *)realloc(resBuf, size * sizeof(TCHAR));
++ if (newBuf == NULL) raise_syscall(taskData, "Insufficient memory", ENOMEM);
++ resBuf = newBuf;
++ }
+ if (nLen < 0) raise_syscall(taskData, "readlink failed", errno);
+ return(SAVE(C_string_to_Poly(taskData, resBuf, nLen)));
+ #endif
+@@ -1780,13 +1795,18 @@
+ raise_syscall(taskData, "GetTempPath failed", -(int)(GetLastError()));
+ lstrcat(buff, _T("MLTEMPXXXXXX"));
+ #else
+- TCHAR buff[MAXPATHLEN];
++ const char *template_subdir = "/MLTEMPXXXXXX";
+ #ifdef P_tmpdir
++ TempString buff((TCHAR *)malloc(strlen(P_tmpdir) + strlen(template_subdir) + 1));
++ if (buff == 0) raise_syscall(taskData, "Insufficient memory", ENOMEM);
+ strcpy(buff, P_tmpdir);
+ #else
+- strcpy(buff, "/tmp");
++ const char *tmpdir = "/tmp";
++ TempString buff((TCHAR *)malloc(strlen(tmpdir) + strlen(template_subdir) + 1));
++ if (buff == 0) raise_syscall(taskData, "Insufficient memory", ENOMEM);
++ strcpy(buff, tmpdir);
+ #endif
+- strcat(buff, "/MLTEMPXXXXXX");
++ strcat(buff, template_subdir);
+ #endif
+
+ #if (defined(HAVE_MKSTEMP) && ! defined(UNICODE))
+--- a/libpolyml/exporter.cpp
++++ b/libpolyml/exporter.cpp
+@@ -82,10 +82,6 @@
+ #include "machoexport.h"
+ #endif
+
+-#if(!defined(MAXPATHLEN) && defined(MAX_PATH))
+-#define MAXPATHLEN MAX_PATH
+-#endif
+-
+ /*
+ To export the function and everything reachable from it we need to copy
+ all the objects into a new area. We leave tombstones in the original
+@@ -416,14 +412,14 @@
+
+ static void exporter(TaskData *taskData, Handle args, const TCHAR *extension, Exporter *exports)
+ {
+- TCHAR fileNameBuff[MAXPATHLEN+MAX_EXTENSION];
+- POLYUNSIGNED length =
+- Poly_string_to_C(DEREFHANDLE(args)->Get(0), fileNameBuff, MAXPATHLEN);
+- if (length > MAXPATHLEN)
+- raise_syscall(taskData, "File name too long", ENAMETOOLONG);
++ size_t extLen = _tcslen(extension);
++ TempString fileNameBuff(Poly_string_to_C_alloc(DEREFHANDLE(args)->Get(0), extLen * sizeof(TCHAR)));
++ if (fileNameBuff == NULL)
++ raise_syscall(taskData, "Insufficient memory", ENOMEM);
++ size_t length = _tcslen(fileNameBuff);
+
+ // Does it already have the extension? If not add it on.
+- if (length < _tcslen(extension) || _tcscmp(fileNameBuff + length - _tcslen(extension), extension) != 0)
++ if (length < extLen || _tcscmp(fileNameBuff + length - extLen, extension) != 0)
+ _tcscat(fileNameBuff, extension);
+ #if (defined(_WIN32) && defined(UNICODE))
+ exports->exportFile = _wfopen(fileNameBuff, L"wb");
+--- a/libpolyml/polystring.cpp
++++ b/libpolyml/polystring.cpp
+@@ -97,7 +97,7 @@
+ return chars;
+ } /* Poly_string_to_C */
+
+-char *Poly_string_to_C_alloc(PolyWord ps)
++char *Poly_string_to_C_alloc(PolyWord ps, size_t buffExtra)
+ /* Similar to Poly_string_to_C except that the string is allocated using
+ malloc and must be freed by the caller. */
+ {
+@@ -105,7 +105,7 @@
+
+ if (IS_INT(ps))
+ {
+- res = (char*)malloc(2);
++ res = (char*)malloc(2 + buffExtra);
+ if (res == 0) return 0;
+ res[0] = (char)(UNTAGGED(ps));
+ res[1] = '\0';
+@@ -114,7 +114,7 @@
+ {
+ PolyStringObject * str = (PolyStringObject *)ps.AsObjPtr();
+ POLYUNSIGNED chars = str->length;
+- res = (char*)malloc(chars+1);
++ res = (char*)malloc(chars + buffExtra + 1);
+ if (res == 0) return 0;
+ if (chars != 0) strncpy(res, str->chars, chars);
+ res[chars] = '\0';
+--- a/libpolyml/polystring.h
++++ b/libpolyml/polystring.h
+@@ -46,7 +46,7 @@
+ /* PolyStringObject functions */
+ extern PolyWord C_string_to_Poly(TaskData *mdTaskData, const char *buffer, size_t buffLen = -1);
+ extern POLYUNSIGNED Poly_string_to_C(PolyWord ps, char *buff, POLYUNSIGNED bufflen);
+-extern char *Poly_string_to_C_alloc(PolyWord ps);
++extern char *Poly_string_to_C_alloc(PolyWord ps, size_t buffExtra = 0);
+
+ extern Handle convert_string_list(TaskData *mdTaskData, int count, char **strings);
+
+--- a/libpolyml/savestate.cpp
++++ b/libpolyml/savestate.cpp
+@@ -101,10 +101,6 @@
+ #include "osmem.h"
+ #include "gc.h" // For FullGC.
+
+-#if(!defined(MAXPATHLEN) && defined(MAX_PATH))
+-#define MAXPATHLEN MAX_PATH
+-#endif
+-
+ #ifdef _MSC_VER
+ // Don't tell me about ISO C++ changes.
+ #pragma warning(disable:4996)
+@@ -653,11 +649,7 @@
+
+ Handle SaveState(TaskData *taskData, Handle args)
+ {
+- TCHAR fileNameBuff[MAXPATHLEN];
+- POLYUNSIGNED length =
+- Poly_string_to_C(DEREFHANDLE(args)->Get(0), fileNameBuff, MAXPATHLEN);
+- if (length > MAXPATHLEN)
+- raise_syscall(taskData, "File name too long", ENAMETOOLONG);
++ TempString fileNameBuff(Poly_string_to_C_alloc(DEREFHANDLE(args)->Get(0)));
+ // The value of depth is zero for top-level save so we need to add one for hierarchy.
+ unsigned newHierarchy = get_C_unsigned(taskData, DEREFHANDLE(args)->Get(1)) + 1;
+
+@@ -694,7 +686,7 @@
+ // The fileName here is the last file loaded. As well as using it
+ // to load the name can also be printed out at the end to identify the
+ // particular file in the hierarchy that failed.
+- TCHAR fileName[MAXPATHLEN];
++ AutoFree<TCHAR*> fileName;
+ int errNumber;
+ };
+
+@@ -710,23 +702,22 @@
+ return;
+ }
+ ML_Cons_Cell *p = DEREFLISTHANDLE(fileNameList);
+- POLYUNSIGNED length = Poly_string_to_C(p->h, fileName, MAXPATHLEN);
+- if (length > MAXPATHLEN)
++ fileName = Poly_string_to_C_alloc(p->h);
++ if (fileName == NULL)
+ {
+- errorResult = "File name too long";
+- errNumber = ENAMETOOLONG;
++ errorResult = "Insufficient memory";
++ errNumber = ENOMEM;
+ return;
+ }
+ (void)LoadFile(true, 0, p->t);
+ }
+ else
+ {
+- POLYUNSIGNED length =
+- Poly_string_to_C(DEREFHANDLE(fileNameList), fileName, MAXPATHLEN);
+- if (length > MAXPATHLEN)
++ fileName = Poly_string_to_C_alloc(DEREFHANDLE(fileNameList));
++ if (fileName == NULL)
+ {
+- errorResult = "File name too long";
+- errNumber = ENAMETOOLONG;
++ errorResult = "Insufficient memory";
++ errNumber = ENOMEM;
+ return;
+ }
+ (void)LoadFile(true, 0, TAGGED(0));
+@@ -867,11 +858,11 @@
+ return false;
+ }
+ ML_Cons_Cell *p = (ML_Cons_Cell *)tail.AsObjPtr();
+- POLYUNSIGNED length = Poly_string_to_C(p->h, fileName, MAXPATHLEN);
+- if (length > MAXPATHLEN)
++ fileName = Poly_string_to_C_alloc(p->h);
++ if (fileName == NULL)
+ {
+- errorResult = "File name too long";
+- errNumber = ENAMETOOLONG;
++ errorResult = "Insufficient memory";
++ errNumber = ENOMEM;
+ return false;
+ }
+ if (! LoadFile(false, header.parentTimeStamp, p->t))
+@@ -880,7 +871,17 @@
+ else
+ {
+ size_t toRead = header.stringTableSize-header.parentNameEntry;
+- if (MAXPATHLEN < toRead) toRead = MAXPATHLEN;
++ size_t elems = ((toRead + sizeof(TCHAR) - 1) / sizeof(TCHAR));
++ // Always allow space for null terminator
++ size_t roundedBytes = (elems + 1) * sizeof(TCHAR);
++ TCHAR *newFileName = (TCHAR *)realloc(fileName, roundedBytes);
++ if (newFileName == NULL)
++ {
++ errorResult = "Insufficient memory";
++ errNumber = ENOMEM;
++ return false;
++ }
++ fileName = newFileName;
+
+ if (header.parentNameEntry >= header.stringTableSize /* Bad entry */ ||
+ fseek(loadFile, header.stringTable + header.parentNameEntry, SEEK_SET) != 0 ||
+@@ -889,7 +890,7 @@
+ errorResult = "Unable to read parent file name";
+ return false;
+ }
+- fileName[toRead] = 0; // Should already be null-terminated, but just in case.
++ fileName[elems] = 0; // Should already be null-terminated, but just in case.
+
+ if (! LoadFile(false, header.parentTimeStamp, TAGGED(0)))
+ return false;
+@@ -1097,11 +1098,11 @@
+ raise_fail(taskData, loader.errorResult);
+ else
+ {
+- char buff[MAXPATHLEN+100];
++ AutoFree<char*> buff((char *)malloc(strlen(loader.errorResult) + 2 + _tcslen(loader.fileName) * sizeof(TCHAR) + 1));
+ #if (defined(_WIN32) && defined(UNICODE))
+- sprintf(buff, "%s: %S", loader.errorResult, loader.fileName);
++ sprintf(buff, "%s: %S", loader.errorResult, (TCHAR *)loader.fileName);
+ #else
+- sprintf(buff, "%s: %s", loader.errorResult, loader.fileName);
++ sprintf(buff, "%s: %s", loader.errorResult, (TCHAR *)loader.fileName);
+ #endif
+ raise_syscall(taskData, buff, loader.errNumber);
+ }
+@@ -1139,26 +1140,23 @@
+ Handle RenameParent(TaskData *taskData, Handle args)
+ // Change the name of the immediate parent stored in a child
+ {
+- TCHAR fileNameBuff[MAXPATHLEN], parentNameBuff[MAXPATHLEN];
+ // The name of the file to modify.
+- POLYUNSIGNED fileLength =
+- Poly_string_to_C(DEREFHANDLE(args)->Get(0), fileNameBuff, MAXPATHLEN);
+- if (fileLength > MAXPATHLEN)
+- raise_syscall(taskData, "File name too long", ENAMETOOLONG);
++ AutoFree<TCHAR*> fileNameBuff(Poly_string_to_C_alloc(DEREFHANDLE(args)->Get(0)));
++ if (fileNameBuff == NULL)
++ raise_syscall(taskData, "Insufficient memory", ENOMEM);
+ // The new parent name to insert.
+- POLYUNSIGNED parentLength =
+- Poly_string_to_C(DEREFHANDLE(args)->Get(1), parentNameBuff, MAXPATHLEN);
+- if (parentLength > MAXPATHLEN)
+- raise_syscall(taskData, "Parent name too long", ENAMETOOLONG);
++ AutoFree<TCHAR*> parentNameBuff(Poly_string_to_C_alloc(DEREFHANDLE(args)->Get(1)));
++ if (parentNameBuff == NULL)
++ raise_syscall(taskData, "Insufficient memory", ENOMEM);
+
+ AutoClose loadFile(_tfopen(fileNameBuff, _T("r+b"))); // Open for reading and writing
+ if ((FILE*)loadFile == NULL)
+ {
+- char buff[MAXPATHLEN+1+23];
++ AutoFree<char*> buff((char *)malloc(23 + _tcslen(fileNameBuff) * sizeof(TCHAR) + 1));
+ #if (defined(_WIN32) && defined(UNICODE))
+- sprintf(buff, "Cannot open load file: %S", fileNameBuff);
++ sprintf(buff, "Cannot open load file: %S", (TCHAR *)fileNameBuff);
+ #else
+- sprintf(buff, "Cannot open load file: %s", fileNameBuff);
++ sprintf(buff, "Cannot open load file: %s", (TCHAR *)fileNameBuff);
+ #endif
+ raise_syscall(taskData, buff, errno);
+ }
+@@ -1203,20 +1201,18 @@
+ Handle ShowParent(TaskData *taskData, Handle hFileName)
+ // Return the name of the immediate parent stored in a child
+ {
+- TCHAR fileNameBuff[MAXPATHLEN+1];
+- POLYUNSIGNED length =
+- Poly_string_to_C(DEREFHANDLE(hFileName), fileNameBuff, MAXPATHLEN);
+- if (length > MAXPATHLEN)
+- raise_syscall(taskData, "File name too long", ENAMETOOLONG);
++ AutoFree<TCHAR*> fileNameBuff(Poly_string_to_C_alloc(DEREFHANDLE(hFileName)));
++ if (fileNameBuff == NULL)
++ raise_syscall(taskData, "Insufficient memory", ENOMEM);
+
+ AutoClose loadFile(_tfopen(fileNameBuff, _T("rb")));
+ if ((FILE*)loadFile == NULL)
+ {
+- char buff[MAXPATHLEN+1+23];
++ AutoFree<char*> buff((char *)malloc(23 + _tcslen(fileNameBuff) * sizeof(TCHAR) + 1));
+ #if (defined(_WIN32) && defined(UNICODE))
+- sprintf(buff, "Cannot open load file: %S", fileNameBuff);
++ sprintf(buff, "Cannot open load file: %S", (TCHAR *)fileNameBuff);
+ #else
+- sprintf(buff, "Cannot open load file: %s", fileNameBuff);
++ sprintf(buff, "Cannot open load file: %s", (TCHAR *)fileNameBuff);
+ #endif
+ raise_syscall(taskData, buff, errno);
+ }
+@@ -1239,9 +1235,13 @@
+ // Does this have a parent?
+ if (header.parentNameEntry != 0)
+ {
+- TCHAR parentFileName[MAXPATHLEN+1];
+ size_t toRead = header.stringTableSize-header.parentNameEntry;
+- if (MAXPATHLEN < toRead) toRead = MAXPATHLEN;
++ size_t elems = ((toRead + sizeof(TCHAR) - 1) / sizeof(TCHAR));
++ // Always allow space for null terminator
++ size_t roundedBytes = (elems + 1) * sizeof(TCHAR);
++ AutoFree<TCHAR*> parentFileName((TCHAR *)malloc(roundedBytes));
++ if (parentFileName == NULL)
++ raise_syscall(taskData, "Insufficient memory", ENOMEM);
+
+ if (header.parentNameEntry >= header.stringTableSize /* Bad entry */ ||
+ fseek(loadFile, header.stringTable + header.parentNameEntry, SEEK_SET) != 0 ||
+@@ -1249,7 +1249,7 @@
+ {
+ raise_fail(taskData, "Unable to read parent file name");
+ }
+- parentFileName[toRead] = 0; // Should already be null-terminated, but just in case.
++ parentFileName[elems] = 0; // Should already be null-terminated, but just in case.
+ // Convert the name into a Poly string and then build a "Some" value.
+ // It's possible, although silly, to have the empty string as a parent name.
+ Handle resVal = SAVE(C_string_to_Poly(taskData, parentFileName));
+@@ -1599,7 +1599,7 @@
+ raise_fail(taskData, loader.errorResult);
+ else
+ {
+- char buff[MAXPATHLEN+100];
++ AutoFree<char*> buff((char *)malloc(strlen(loader.errorResult) + 2 + _tcslen(loader.fileName) * sizeof(TCHAR) + 1));
+ #if (defined(_WIN32) && defined(UNICODE))
+ sprintf(buff, "%s: %S", loader.errorResult, loader.fileName);
+ #else
+--- a/libpolyml/statistics.cpp
++++ b/libpolyml/statistics.cpp
+@@ -669,13 +669,26 @@
+ return result;
+ #elif HAVE_MMAP
+ // Find the shared memory in the user's home directory
+- int remMapFd = -1;
+- char remMapFileName[MAXPATHLEN];
+- remMapFileName[0] = 0;
+ char *homeDir = getenv("HOME");
+ if (homeDir == NULL)
+ raise_exception_string(taskData, EXC_Fail, "No statistics available");
+- sprintf(remMapFileName, "%s/.polyml/" POLY_STATS_NAME "%" POLYUFMT, homeDir, pid);
++
++ int remMapFd = -1;
++ size_t remMapSize = 4096;
++ TempCString remMapFileName((char *)malloc(remMapSize));
++ if (remMapFileName == NULL)
++ raise_exception_string(taskData, EXC_Fail, "No statistics available");
++
++ while ((snprintf(remMapFileName, remMapSize, "%s/.polyml/" POLY_STATS_NAME "%" POLYUFMT, homeDir, pid), strlen(remMapFileName) >= remMapSize - 1)) {
++ if (remMapSize > SIZE_MAX / 2)
++ raise_exception_string(taskData, EXC_Fail, "No statistics available");
++ remMapSize *= 2;
++ char *newFileName = (char *)realloc(remMapFileName, remMapSize);
++ if (newFileName == NULL)
++ raise_exception_string(taskData, EXC_Fail, "No statistics available");
++ remMapFileName = newFileName;
++ }
++
+ remMapFd = open(remMapFileName, O_RDONLY);
+ if (remMapFd == -1)
+ raise_exception_string(taskData, EXC_Fail, "No statistics available");
diff --git a/debian/patches/series b/debian/patches/series
index c48e2cf..2687ca5 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -14,3 +14,4 @@ alpha.diff
m68k.diff
mips64.diff
x32.diff
+maxpathlen.diff
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/polyml.git
More information about the debian-science-commits
mailing list