feature. See also
. The project being documented here (as the example) is the Zig library itself.
Threaded.isCygwinPty
fn isCygwinPty(file: File) Io.Cancelable!bool
File
Code
fn isCygwinPty(file: File) Io.Cancelable!bool {
if (!is_windows) return false;
const handle = file.handle;
// msys-[...]-ptyN-[...]
// cygwin-[...]-ptyN-[...]
//
// Example: msys-1888ae32e00d56aa-pty0-to-master
// First, just check that the handle is a named pipe.
// This allows us to avoid the more costly NtQueryInformationFile call
// for handles that aren't named pipes.
{
var io_status: windows.IO_STATUS_BLOCK = undefined;
var device_info: windows.FILE.FS_DEVICE_INFORMATION = undefined;
const syscall: Syscall = try .start();
while (true) switch (windows.ntdll.NtQueryVolumeInformationFile(
handle,
&io_status,
&device_info,
@sizeOf(windows.FILE.FS_DEVICE_INFORMATION),
.Device,
)) {
.SUCCESS => break syscall.finish(),
.CANCELLED => {
try syscall.checkCancel();
continue;
},
else => {
syscall.finish();
return false;
},
};
if (device_info.DeviceType.FileDevice != .NAMED_PIPE) return false;
}
const name_bytes_offset = @offsetOf(windows.FILE.NAME_INFORMATION, "FileName");
// This buffer may not be long enough to handle *all* possible paths
// (PATH_MAX_WIDE would be necessary for that), but because we only care
// about certain paths and we know they must be within a reasonable length,
// we can use this smaller buffer and just return false on any error from
// NtQueryInformationFile.
const num_name_bytes = windows.MAX_PATH * 2;
var name_info_bytes: [name_bytes_offset + num_name_bytes]u8 align(@alignOf(windows.FILE.NAME_INFORMATION)) = @splat(0);
var io_status_block: windows.IO_STATUS_BLOCK = undefined;
const syscall: Syscall = try .start();
while (true) switch (windows.ntdll.NtQueryInformationFile(
handle,
&io_status_block,
&name_info_bytes,
@intCast(name_info_bytes.len),
.Name,
)) {
.SUCCESS => break syscall.finish(),
.CANCELLED => {
try syscall.checkCancel();
continue;
},
.INVALID_PARAMETER => unreachable,
else => {
syscall.finish();
return false;
},
};
const name_info: *const windows.FILE.NAME_INFORMATION = @ptrCast(&name_info_bytes);
const name_bytes = name_info_bytes[name_bytes_offset .. name_bytes_offset + name_info.FileNameLength];
const name_wide = std.mem.bytesAsSlice(u16, name_bytes);
return (std.mem.startsWith(u16, name_wide, &[_]u16{ '\\', 'm', 's', 'y', 's', '-' }) or
std.mem.startsWith(u16, name_wide, &[_]u16{ '\\', 'c', 'y', 'g', 'w', 'i', 'n', '-' })) and
std.mem.indexOf(u16, name_wide, &[_]u16{ '-', 'p', 't', 'y' }) != null;
}