Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 18 additions & 10 deletions std/file.d
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@ version (Posix) private void[] readImpl(const(char)[] name, const(FSChar)* namez
import std.algorithm.comparison : min;
import std.array : uninitializedArray;
import std.conv : to;
import std.experimental.checkedint : checked;

// A few internal configuration parameters {
enum size_t
Expand All @@ -358,24 +359,25 @@ version (Posix) private void[] readImpl(const(char)[] name, const(FSChar)* namez
: minInitialAlloc));
void[] result = uninitializedArray!(ubyte[])(initialAlloc);
scope(failure) GC.free(result.ptr);
size_t size = 0;

auto size = checked(size_t(0));

for (;;)
{
immutable actual = core.sys.posix.unistd.read(fd, result.ptr + size,
min(result.length, upTo) - size);
immutable actual = core.sys.posix.unistd.read(fd, result.ptr + size.get,
(min(result.length, upTo) - size).get);
cenforce(actual != -1, name, namez);
if (actual == 0) break;
size += actual;
if (size >= upTo) break;
if (size < result.length) continue;
immutable newAlloc = size + sizeIncrement;
result = GC.realloc(result.ptr, newAlloc, GC.BlkAttr.NO_SCAN)[0 .. newAlloc];
result = GC.realloc(result.ptr, newAlloc.get, GC.BlkAttr.NO_SCAN)[0 .. newAlloc.get];
}

return result.length - size >= maxSlackMemoryAllowed
? GC.realloc(result.ptr, size, GC.BlkAttr.NO_SCAN)[0 .. size]
: result[0 .. size];
? GC.realloc(result.ptr, size.get, GC.BlkAttr.NO_SCAN)[0 .. size.get]
: result[0 .. size.get];
}


Expand Down Expand Up @@ -2645,14 +2647,19 @@ version(Posix) @system unittest // input range of dchars
version(Windows) string getcwd()
{
import std.conv : to;
import std.experimental.checkedint : checked;
/* GetCurrentDirectory's return value:
1. function succeeds: the number of characters that are written to
the buffer, not including the terminating null character.
2. function fails: zero
3. the buffer (lpBuffer) is not large enough: the required size of
the buffer, in characters, including the null-terminating character.
*/
wchar[4096] buffW = void; //enough for most common case
version (StdUnittest)
enum BUF_SIZE = 10; // trigger reallocation code
else
enum BUF_SIZE = 4096; // enough for most common case
wchar[BUF_SIZE] buffW = void;
immutable n = cenforce(GetCurrentDirectoryW(to!DWORD(buffW.length), buffW.ptr),
"getcwd");
// we can do it because toUTFX always produces a fresh string
Expand All @@ -2662,10 +2669,11 @@ version(Windows) string getcwd()
}
else //staticBuff isn't enough
{
auto ptr = cast(wchar*) malloc(wchar.sizeof * n);
auto cn = checked(n);
auto ptr = cast(wchar*) malloc((cn * wchar.sizeof).get);
scope(exit) free(ptr);
immutable n2 = GetCurrentDirectoryW(n, ptr);
cenforce(n2 && n2 < n, "getcwd");
immutable n2 = GetCurrentDirectoryW(cn.get, ptr);
cenforce(n2 && n2 < cn, "getcwd");
return ptr[0 .. n2].to!string;
}
}
Expand Down