Skip to content

Commit

Permalink
feat: flush
Browse files Browse the repository at this point in the history
  • Loading branch information
mochalins committed Sep 15, 2024
1 parent 51d0ebd commit 3a43dae
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 14 deletions.
59 changes: 53 additions & 6 deletions src/backend/posix.zig
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,14 @@ pub const Port = struct {
});
}

pub fn configure(self: *@This(), config: serialport.Config) !void {
pub fn close(self: *@This()) void {
if (self.file) |f| {
f.close();
self.file = null;
}
}

pub fn configure(self: @This(), config: serialport.Config) !void {
if (self.file == null) return;

var settings = try std.posix.tcgetattr(self.file.?.handle);
Expand Down Expand Up @@ -80,11 +87,20 @@ pub const Port = struct {
try std.posix.tcsetattr(self.file.?.handle, .NOW, settings);
}

pub fn close(self: *@This()) void {
if (self.file) |f| {
f.close();
self.file = null;
}
pub fn flush(
self: @This(),
options: serialport.ManagedPort.FlushOptions,
) !void {
if ((!options.input and !options.output) or self.file == null) return;
try tcflush(
self.file.?.handle,
if (options.input and options.output)
.IO
else if (options.input)
.I
else
.O,
);
}

pub fn reader(self: @This()) ?Reader {
Expand All @@ -104,3 +120,34 @@ pub const Port = struct {
self.* = undefined;
}
};

const TCFLUSH = switch (builtin.os.tag) {
.openbsd => std.c.TCFLUSH,
else => enum(usize) {
I = 0,
O = 1,
IO = 2,
},
};

fn tcflush(fd: std.posix.fd_t, action: TCFLUSH) !void {
const result = switch (comptime builtin.os.tag) {
.linux => b: {
const TCFLSH = 0x540B;
break :b std.os.linux.syscall3(
.ioctl,
@bitCast(@as(isize, @intCast(fd))),
TCFLSH,
@intFromEnum(action),
);
},
.macos => try std.c.tcflush(fd, @intFromEnum(action)),
else => @compileError("tcflush unimplemented on this OS"),
};
return switch (std.posix.errno(result)) {
.SUCCESS => {},
.BADF => error.FileNotFound,
.NOTTY => error.FileNotTty,
else => unreachable,
};
}
34 changes: 29 additions & 5 deletions src/backend/windows.zig
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,14 @@ pub const Port = struct {
}
}

pub fn configure(self: *@This(), config: serialport.Config) !void {
pub fn close(self: *@This()) void {
if (self.file) |f| {
f.close();
self.file = null;
}
}

pub fn configure(self: @This(), config: serialport.Config) !void {
if (self.file == null) return;

var dcb: DCB = std.mem.zeroes(DCB);
Expand Down Expand Up @@ -103,10 +110,16 @@ pub const Port = struct {
}
}

pub fn close(self: *@This()) void {
if (self.file) |f| {
f.close();
self.file = null;
pub fn flush(
self: @This(),
options: serialport.ManagedPort.FlushOptions,
) !void {
if ((!options.input and !options.output) or self.file == null) return;
if (PurgeComm(self.file.?.handle, .{
.PURGE_TXCLEAR = options.output,
.PURGE_RXCLEAR = options.input,
}) == 0) {
return windows.unexpectedError(windows.GetLastError());
}
}

Expand Down Expand Up @@ -287,3 +300,14 @@ extern "kernel32" fn GetCommState(
hFile: windows.HANDLE,
lpDCB: *DCB,
) callconv(windows.WINAPI) windows.BOOL;

extern "kernel32" fn PurgeComm(
hFile: windows.HANDLE,
dwFlags: packed struct(windows.DWORD) {
PURGE_TXABORT: bool = false,
PURGE_RXABORT: bool = false,
PURGE_TXCLEAR: bool = false,
PURGE_RXCLEAR: bool = false,
_: u28 = 0,
},
) callconv(windows.WINAPI) windows.BOOL;
15 changes: 12 additions & 3 deletions src/serialport.zig
Original file line number Diff line number Diff line change
Expand Up @@ -67,16 +67,25 @@ pub const ManagedPort = struct {
pub const Writer = Port.Writer;
pub const WriteError = Port.WriteError;

pub const FlushOptions = struct {
input: bool = false,
output: bool = false,
};

pub fn open(self: *@This()) !void {
return self.port.open();
}

pub fn configure(self: *@This(), config: Config) !void {
pub fn close(self: *@This()) void {
self.port.close();
}

pub fn configure(self: @This(), config: Config) !void {
return self.port.configure(config);
}

pub fn close(self: *@This()) void {
self.port.close();
pub fn flush(self: @This(), options: FlushOptions) !void {
return self.port.flush(options);
}

pub fn reader(self: @This()) ?Reader {
Expand Down

0 comments on commit 3a43dae

Please sign in to comment.