aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2013-03-19 23:03:01 -0500
committerJesse Luehrs <doy@tozt.net>2013-03-19 23:03:01 -0500
commitd81b604ed963ac571bbeefa033b7744ad3f51d5e (patch)
tree8e0901e3974aec7400a0b46275277249fc2e4263 /src
parent1fa0019d580450ab106d2a1f3ed9c622218c0dbf (diff)
downloadrust-term-d81b604ed963ac571bbeefa033b7744ad3f51d5e.tar.gz
rust-term-d81b604ed963ac571bbeefa033b7744ad3f51d5e.zip
add a scope guard sort of thing to allow restoring terminal state
Diffstat (limited to 'src')
-rw-r--r--src/ios.rs19
-rw-r--r--src/termios_wrapper.c23
2 files changed, 42 insertions, 0 deletions
diff --git a/src/ios.rs b/src/ios.rs
index f8b464a..2e5bd17 100644
--- a/src/ios.rs
+++ b/src/ios.rs
@@ -1,11 +1,30 @@
use core::libc::c_int;
+enum struct_termios {}
+
+pub struct PreserveTermios {
+ priv state: *struct_termios,
+}
+
+pub fn PreserveTermios () -> ~PreserveTermios {
+ ~PreserveTermios { state: unsafe { c::get() } }
+}
+
+impl Drop for PreserveTermios {
+ fn finalize (&self) {
+ unsafe { c::set(self.state) }
+ }
+}
+
#[link_name = "termios_wrapper"]
extern mod c {
fn cooked () -> c_int;
fn cbreak () -> c_int;
fn raw () -> c_int;
fn echo (enable: c_int) -> c_int;
+
+ fn get() -> *struct_termios;
+ fn set(t: *struct_termios);
}
pub fn cooked () -> bool {
diff --git a/src/termios_wrapper.c b/src/termios_wrapper.c
index b23ae2d..77d589b 100644
--- a/src/termios_wrapper.c
+++ b/src/termios_wrapper.c
@@ -1,3 +1,4 @@
+#include <stdlib.h>
#include <termios.h>
/* very simplistic, ignores a lot of the settings that i don't understand,
@@ -63,3 +64,25 @@ int echo(int enabled)
return tcsetattr(0, TCSANOW, &t) == 0;
}
+
+struct termios *get()
+{
+ struct termios *t;
+
+ t = malloc(sizeof(struct termios));
+ if (tcgetattr(0, t) == -1) {
+ return NULL;
+ }
+
+ return t;
+}
+
+void set(struct termios *t)
+{
+ if (t == NULL) {
+ return;
+ }
+
+ tcsetattr(0, TCSANOW, t);
+ free(t);
+}