Skip to content

Commit

Permalink
Fix issue on Windows with HANDLE being confused with an io opaque
Browse files Browse the repository at this point in the history
handle. This adds an opaque handle type that can then be used without
knowing what the underlying OS handle type is. Avoiding a direct alias
means the type is distinct for std.io, and can't be confused with other
opaque types (as was the case for Windows). Closes #20.
  • Loading branch information
schveiguy committed Oct 14, 2019
1 parent 5a5f610 commit 9e145c0
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 25 deletions.
23 changes: 16 additions & 7 deletions src/std/io/driver/package.d
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ package
static assert(0, "unimplemented");
}

/// All handles in std.io are based on this type. The implementation defines how it is used.
struct OpaqueHandle
{
enum OpaqueHandle INVALID = OpaqueHandle(cast(void*)-1);
void *handle;
}

/**
The driver interface used by std.io.
Expand All @@ -39,16 +46,14 @@ interface Driver
{
// FILE and SOCKET handles cannot be manipulated in @safe code, so most of
// the Driver's API is @safe.
shared @safe @nogc:
@safe @nogc:
/**
Opaque file handle
Interpretation left to driver, typically `int` file descriptor
on Posix systems and `HANDLE` on Windows.
*/
alias FILE = void*;
/// value used for invalid/closed files
enum INVALID_FILE = cast(void*)-1;
alias FILE = OpaqueHandle;

version (Posix)
alias tchar = char; /// UTF-8 path on Posix, UTF-16 path on Windows
Expand All @@ -57,6 +62,7 @@ shared @safe @nogc:
else
static assert(0, "unimplemented");

shared {
/**
Create/open file at `path` in `mode`.
Expand All @@ -83,16 +89,18 @@ shared @safe @nogc:
size_t write(scope FILE f, /*in*/ const scope ubyte[][] bufs);
/// seek file to offset
ulong seek(scope FILE f, long offset, int whence);
}

/**
Opaque socket handle
Interpretation left to driver, typically `int` file descriptor
on Posix systems and `SOCKET` on Windows.
*/
alias SOCKET = void*;
/// value used for invalid/closed sockets
enum INVALID_SOCKET = cast(void*)-1;
alias SOCKET = OpaqueHandle;


shared {
/// create socket
SOCKET createSocket(AddrFamily family, SocketType type, Protocol protocol);
/**
Expand Down Expand Up @@ -151,6 +159,7 @@ shared @safe @nogc:
int resolve( /*in*/ const scope char[] hostname, /*in*/ const scope char[] service, AddrFamily family,
SocketType socktype, Protocol protocol,
scope int delegate(const scope ref AddrInfo ai) @safe @nogc cb);
}

///
@safe @nogc unittest
Expand Down
16 changes: 8 additions & 8 deletions src/std/io/driver/sync.d
Original file line number Diff line number Diff line change
Expand Up @@ -525,27 +525,27 @@ version (Posix)
/// handle to file
Driver.FILE h2f(return scope int fd) pure nothrow @trusted @nogc
{
return cast(void*) fd;
return Driver.FILE(cast(void*) fd);
}

/// file to handle
int f2h(scope Driver.FILE f) pure nothrow @trusted @nogc
{
return cast(int) f;
return cast(int) f.handle;
}

static assert(int.sizeof <= Driver.SOCKET.sizeof);

/// handle to socket
Driver.SOCKET h2s(return scope int fd) pure nothrow @trusted @nogc
{
return cast(Driver.SOCKET) fd;
return Driver.SOCKET(cast(void *)fd);
}

/// socket to handle
inout(int) s2h(scope inout Driver.SOCKET s) pure nothrow @trusted @nogc
{
return cast(int) s;
return cast(int) s.handle;
}
}
else version (Windows)
Expand All @@ -557,27 +557,27 @@ else version (Windows)
/// handle to file
Driver.FILE h2f(return scope HANDLE fd) pure nothrow @trusted @nogc
{
return cast(Driver.FILE) fd;
return Driver.FILE(cast(void*)fd);
}

/// file to handle
HANDLE f2h(return scope Driver.FILE f) pure nothrow @trusted @nogc
{
return cast(HANDLE) f;
return cast(HANDLE) f.handle;
}

static assert(ws2.SOCKET.sizeof <= Driver.SOCKET.sizeof);

/// handle to socket
Driver.SOCKET h2s(return scope ws2.SOCKET fd) pure nothrow @trusted @nogc
{
return cast(Driver.SOCKET) fd;
return Driver.SOCKET(cast(void *)fd);
}

/// socket to handle
inout(ws2.SOCKET) s2h(scope inout Driver.SOCKET s) pure nothrow @trusted @nogc
{
return cast(ws2.SOCKET) s;
return cast(ws2.SOCKET) s.handle;
}
}

Expand Down
10 changes: 5 additions & 5 deletions src/std/io/file.d
Original file line number Diff line number Diff line change
Expand Up @@ -189,16 +189,16 @@ struct File
/// close the file
void close() scope @trusted
{
if (f is Driver.INVALID_FILE)
if (f is Driver.FILE.INVALID)
return;
driver.closeFile(f);
f = Driver.INVALID_FILE;
f = Driver.FILE.INVALID;
}

/// return whether file is open
bool isOpen() const scope
{
return f != Driver.INVALID_FILE;
return f != Driver.FILE.INVALID;
}

///
Expand Down Expand Up @@ -353,7 +353,7 @@ struct File
File move() return scope nothrow /*pure Issue 18590*/
{
auto f = this.f;
this.f = Driver.INVALID_FILE;
this.f = Driver.FILE.INVALID;
return File(f);
}

Expand All @@ -367,7 +367,7 @@ private:
this.f = f;
}

Driver.FILE f = Driver.INVALID_FILE;
Driver.FILE f = Driver.FILE.INVALID;
}

///
Expand Down
10 changes: 5 additions & 5 deletions src/std/io/net/socket.d
Original file line number Diff line number Diff line change
Expand Up @@ -127,16 +127,16 @@ struct Socket
/// close the socket
void close() @trusted
{
if (s == Driver.INVALID_SOCKET)
if (s == Driver.SOCKET.INVALID)
return;
driver.closeSocket(s);
s = Driver.INVALID_SOCKET;
s = Driver.SOCKET.INVALID;
}

/// return whether the socket is open
bool isOpen() const pure nothrow
{
return s != Driver.INVALID_SOCKET;
return s != Driver.SOCKET.INVALID;
}

///
Expand Down Expand Up @@ -552,7 +552,7 @@ struct Socket
Socket move() return scope nothrow /*pure Issue 18590*/
{
auto s = this.s;
this.s = Driver.INVALID_SOCKET;
this.s = Driver.SOCKET.INVALID;
return Socket(s);
}

Expand Down Expand Up @@ -611,5 +611,5 @@ private:
this.s = s;
}

Driver.SOCKET s = Driver.INVALID_SOCKET;
Driver.SOCKET s = Driver.SOCKET.INVALID;
}

0 comments on commit 9e145c0

Please sign in to comment.