[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