feature. See also
. The project being documented here (as the example) is the Zig library itself.
Threaded.getNamedPipeDevice
fn getNamedPipeDevice(t: *Threaded) !windows.HANDLE
File
Code
fn getNamedPipeDevice(t: *Threaded) !windows.HANDLE {
{
mutexLock(&t.mutex);
defer mutexUnlock(&t.mutex);
if (t.pipe_file.handle) |handle| return handle;
}
var fresh_handle: windows.HANDLE = undefined;
var io_status_block: windows.IO_STATUS_BLOCK = undefined;
var syscall: Syscall = try .start();
while (true) switch (windows.ntdll.NtOpenFile(
&fresh_handle,
.{ .STANDARD = .{ .SYNCHRONIZE = true } },
&.{
.ObjectName = @constCast(&windows.UNICODE_STRING.init(
&.{ '\\', 'D', 'e', 'v', 'i', 'c', 'e', '\\', 'N', 'a', 'm', 'e', 'd', 'P', 'i', 'p', 'e', '\\' },
)),
},
&io_status_block,
.VALID_FLAGS,
.{ .IO = .SYNCHRONOUS_NONALERT },
)) {
.SUCCESS => {
syscall.finish();
mutexLock(&t.mutex);
defer mutexUnlock(&t.mutex);
if (t.pipe_file.handle) |prev_handle| {
windows.CloseHandle(fresh_handle);
return prev_handle;
} else {
t.pipe_file.handle = fresh_handle;
return fresh_handle;
}
},
.DELETE_PENDING => {
// the file system, but it was deleted. However, the OS is not
// finished with the deletion operation, and so this CreateFile
// call has failed. There is not really a sane way to handle
// this other than retrying the creation after the OS finishes
// the deletion.
syscall.finish();
try parking_sleep.sleep(.{ .duration = .{
.raw = .fromMilliseconds(1),
.clock = .awake,
} });
syscall = try .start();
continue;
},
.CANCELLED => {
try syscall.checkCancel();
continue;
},
.INVALID_PARAMETER => |status| return syscall.ntstatusBug(status),
.OBJECT_PATH_SYNTAX_BAD => |status| return syscall.ntstatusBug(status),
.INVALID_HANDLE => |status| return syscall.ntstatusBug(status),
.OBJECT_NAME_INVALID => return syscall.fail(error.BadPathName),
.OBJECT_NAME_NOT_FOUND => return syscall.fail(error.FileNotFound),
.OBJECT_PATH_NOT_FOUND => return syscall.fail(error.FileNotFound),
.NO_MEDIA_IN_DEVICE => return syscall.fail(error.NoDevice),
.SHARING_VIOLATION => return syscall.fail(error.AccessDenied),
.ACCESS_DENIED => return syscall.fail(error.AccessDenied),
.PIPE_NOT_AVAILABLE => return syscall.fail(error.NoDevice),
.FILE_IS_A_DIRECTORY => return syscall.fail(error.IsDir),
.NOT_A_DIRECTORY => return syscall.fail(error.NotDir),
.USER_MAPPED_FILE => return syscall.fail(error.AccessDenied),
else => |status| return syscall.unexpectedNtstatus(status),
};
}