Skip to content

Commit 42a5e51

Browse files
committed
Fix (pty): Fix type for auto adjust to target pty.rs
to fix new build issue
1 parent 5fc9bad commit 42a5e51

File tree

1 file changed

+68
-68
lines changed

1 file changed

+68
-68
lines changed

shai-cli/src/shell/pty.rs

Lines changed: 68 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -26,24 +26,24 @@ fn generate_session_id() -> String {
2626
use std::collections::hash_map::DefaultHasher;
2727
use std::hash::{Hash, Hasher};
2828
use std::time::{SystemTime, UNIX_EPOCH};
29-
29+
3030
let timestamp = SystemTime::now()
3131
.duration_since(UNIX_EPOCH)
3232
.unwrap()
3333
.as_nanos();
3434
let pid = std::process::id();
3535
let thread_id = std::thread::current().id();
36-
36+
3737
let mut hasher = DefaultHasher::new();
3838
timestamp.hash(&mut hasher);
3939
pid.hash(&mut hasher);
4040
thread_id.hash(&mut hasher);
41-
41+
4242
let stack_var = 42u64;
4343
(&stack_var as *const u64 as usize).hash(&mut hasher);
44-
44+
4545
let hash = hasher.finish();
46-
46+
4747
format!("{:016x}_{}", hash, pid)
4848
}
4949

@@ -57,9 +57,9 @@ pub struct ShaiPtyManager {
5757
impl ShaiPtyManager {
5858
pub fn new() -> Result<Self, Box<dyn std::error::Error>> {
5959
let (master_fd, slave_fd) = Self::create_pty_pair()?;
60-
Ok(Self {
61-
master_fd,
62-
slave_fd,
60+
Ok(Self {
61+
master_fd,
62+
slave_fd,
6363
session_id: generate_session_id(),
6464
temp_rc_file: None,
6565
})
@@ -94,11 +94,11 @@ impl ShaiPtyManager {
9494
std::ffi::CStr::from_ptr(ptr).to_string_lossy().into_owned()
9595
};
9696

97-
let slave_fd = unsafe {
97+
let slave_fd = unsafe {
9898
libc::open(
99-
slave_name.as_ptr() as *const i8,
99+
slave_name.as_ptr() as *const i8,
100100
libc::O_RDWR | libc::O_NOCTTY
101-
)
101+
)
102102
};
103103
if slave_fd == -1 {
104104
unsafe { libc::close(master_fd) };
@@ -118,45 +118,45 @@ impl ShaiPtyManager {
118118
self.setup_window_resize_handler()?;
119119

120120
let pid = unsafe { libc::fork() };
121-
121+
122122
if pid == 0 {
123-
// CHILD: Become the shell
124-
self.setup_child_process(shell, quiet);
123+
// CHILD: Become the shell
124+
self.setup_child_process(shell, quiet);
125125
} else if pid > 0 {
126126
// PARENT: Handle I/O and run buffer server
127127
unsafe { libc::close(self.slave_fd) };
128-
129-
let io_server = ShaiSessionServer::new(&self.session_id, 100, 1000);
128+
129+
let io_server = ShaiSessionServer::new(&self.session_id, 100, 1000);
130130
io_server.start()?;
131131

132132
self.inject_shai_hooks(&shell)?;
133133

134134
self.handle_io_forwarding(io_server, pid)?;
135-
135+
136136
MASTER_FD.store(-1, Ordering::Relaxed);
137137
unsafe { libc::close(self.master_fd) };
138138
terminal.restore();
139139
} else {
140140
// FORK FAILED
141-
unsafe {
141+
unsafe {
142142
libc::close(self.master_fd);
143143
libc::close(self.slave_fd);
144144
};
145145
MASTER_FD.store(-1, Ordering::Relaxed);
146146
terminal.restore();
147147
return Err("Fork failed".into());
148148
}
149-
149+
150150
Ok(())
151151
}
152152

153153
fn inject_shai_hooks(&mut self, shell: &Shell) -> Result<(), Box<dyn std::error::Error>> {
154154
// Create temp file with RC content
155155
let mut temp_file = NamedTempFile::new()?;
156156
temp_file.write_all(shell.generate_rc_content().as_bytes())?;
157-
temp_file.flush()?;
157+
temp_file.flush()?;
158158
let temp_path = temp_file.path().to_string_lossy();
159-
159+
160160
// create source cmd
161161
let source_cmd = match shell.shell_type {
162162
ShellType::Bash | ShellType::Sh | ShellType::Zsh | ShellType::Fish => {
@@ -166,20 +166,20 @@ impl ShaiPtyManager {
166166
format!(". '{}'\n", temp_path)
167167
}
168168
};
169-
169+
170170
// Send source command to shell via stdin
171171
let bytes_written = unsafe {
172172
libc::write(
173-
self.master_fd,
174-
source_cmd.as_ptr() as *const libc::c_void,
173+
self.master_fd,
174+
source_cmd.as_ptr() as *const libc::c_void,
175175
source_cmd.len()
176176
)
177177
};
178-
178+
179179
if bytes_written == -1 {
180180
return Err("Failed to inject shai hooks".into());
181181
}
182-
182+
183183
let (_file, kept_path) = temp_file.keep()?;
184184
self.temp_rc_file = Some(kept_path);
185185

@@ -192,44 +192,44 @@ impl ShaiPtyManager {
192192
sa.sa_sigaction = handle_sigwinch as usize;
193193
libc::sigemptyset(&mut sa.sa_mask);
194194
sa.sa_flags = libc::SA_RESTART;
195-
195+
196196
libc::sigaction(libc::SIGWINCH, &sa, std::ptr::null_mut());
197197
}
198-
198+
199199
Ok(())
200200
}
201201

202202
fn setup_child_process(&self, shell: Shell, quiet: bool) -> ! {
203203
unsafe {
204204
libc::close(self.master_fd);
205-
205+
206206
// Set SHAI_SESSION_ID environment variable
207207
let session_env = std::ffi::CString::new("SHAI_SESSION_ID").unwrap();
208208
let session_value = std::ffi::CString::new(self.session_id.as_str()).unwrap();
209209
libc::setenv(session_env.as_ptr(), session_value.as_ptr(), 1);
210-
210+
211211
if quiet {
212212
let tmux_env = std::ffi::CString::new("TMUX").unwrap();
213213
libc::unsetenv(tmux_env.as_ptr());
214-
214+
215215
let term_session_env = std::ffi::CString::new("TERM_SESSION_ID").unwrap();
216216
libc::unsetenv(term_session_env.as_ptr());
217217
}
218-
218+
219219
libc::setsid();
220-
221-
if libc::ioctl(self.slave_fd, libc::TIOCSCTTY as libc::c_ulong, 0) == -1 {
220+
221+
if libc::ioctl(self.slave_fd, libc::TIOCSCTTY.try_into().unwrap(), 0) == -1 {
222222
libc::exit(1);
223223
}
224-
224+
225225
libc::dup2(self.slave_fd, libc::STDIN_FILENO);
226226
libc::dup2(self.slave_fd, libc::STDOUT_FILENO);
227227
libc::dup2(self.slave_fd, libc::STDERR_FILENO);
228-
228+
229229
if self.slave_fd > 2 {
230230
libc::close(self.slave_fd);
231231
}
232-
232+
233233
let shell_cstr = std::ffi::CString::new(shell.path).unwrap();
234234
let interactive_arg = std::ffi::CString::new("-i").unwrap();
235235
libc::execl(shell_cstr.as_ptr(), shell_cstr.as_ptr(), interactive_arg.as_ptr(), std::ptr::null::<i8>());
@@ -239,18 +239,18 @@ impl ShaiPtyManager {
239239

240240
fn handle_io_forwarding(&self, io_server: ShaiSessionServer, child_pid: i32) -> Result<(), Box<dyn std::error::Error>> {
241241
let master_fd_clone = self.master_fd;
242-
242+
243243
// loop to handle user input and send it to shell stdin
244244
let _stdin_thread = thread::spawn(move || {
245245
let mut stdin = io::stdin();
246246
let mut buffer = [0u8; 1024];
247-
247+
248248
loop {
249249
match stdin.read(&mut buffer) {
250250
Ok(0) => break, // EOF
251251
Ok(n) => {
252252
let input = &buffer[..n];
253-
253+
254254
if unsafe { libc::write(master_fd_clone, input.as_ptr() as *const libc::c_void, n) } == -1 {
255255
break;
256256
}
@@ -263,7 +263,7 @@ impl ShaiPtyManager {
263263
let mut stdout = io::stdout();
264264
let mut buffer = [0u8; 1024];
265265

266-
266+
267267
// consume until MAGIC_COOKIE is read (this is to avoid ugly sourcing echo)
268268
if self.temp_rc_file.is_some() {
269269
let cookie = format!("{}",MAGIC_COOKIE).into_bytes();
@@ -276,29 +276,29 @@ impl ShaiPtyManager {
276276
while unsafe { libc::read(self.master_fd, b.as_mut_ptr() as *mut _, 1) } > 0 {
277277
if b[0] != b'\r' && b[0] == b'\n' {
278278
break;
279-
}
279+
}
280280
}
281-
}
281+
}
282282

283283
// loop to handle shell stdout and print it to user tty
284284
loop {
285-
let bytes_read = unsafe {
286-
libc::read(self.master_fd, buffer.as_mut_ptr() as *mut libc::c_void, buffer.len())
285+
let bytes_read = unsafe {
286+
libc::read(self.master_fd, buffer.as_mut_ptr() as *mut libc::c_void, buffer.len())
287287
};
288-
288+
289289
if bytes_read <= 0 { break; }
290-
290+
291291
let output_data = &buffer[..bytes_read as usize];
292292
io_server.add_output(output_data);
293-
293+
294294
if stdout.write_all(output_data).is_err() { break; }
295295
stdout.flush().ok();
296296
}
297297

298298

299299
// wait for both loop to end
300300
let mut status = 0;
301-
unsafe {
301+
unsafe {
302302
libc::waitpid(child_pid, &mut status, 0);
303303
};
304304

@@ -340,12 +340,12 @@ mod tests {
340340
#[test]
341341
fn test_pty_manager_creation() {
342342
let pty = ShaiPtyManager::new().unwrap();
343-
343+
344344
// Should have valid file descriptors
345345
assert!(pty.master_fd >= 0);
346346
assert!(pty.slave_fd >= 0);
347347
assert!(pty.master_fd != pty.slave_fd);
348-
348+
349349
// Should have a session ID
350350
assert!(!pty.get_session_id().is_empty());
351351
assert!(pty.get_session_id().contains("_")); // timestamp_pid format
@@ -355,46 +355,46 @@ mod tests {
355355
fn test_session_id_format() {
356356
let pty = ShaiPtyManager::new().unwrap();
357357
let session_id = pty.get_session_id();
358-
358+
359359
// Should be in format: hash_pid
360360
let parts: Vec<&str> = session_id.split('_').collect();
361361
assert_eq!(parts.len(), 2);
362-
362+
363363
// First part should be a hex hash (16 characters)
364364
let hash_part = parts[0];
365365
assert_eq!(hash_part.len(), 16, "Hash should be 16 hex characters");
366366
assert!(hash_part.chars().all(|c| c.is_ascii_hexdigit()), "Hash should only contain hex digits");
367-
367+
368368
// Second part should be a PID (number)
369369
assert!(parts[1].parse::<u32>().is_ok(), "Second part should be a valid PID");
370-
370+
371371
// Verify it matches current process PID
372372
let expected_pid = std::process::id();
373373
let actual_pid: u32 = parts[1].parse().unwrap();
374374
assert_eq!(actual_pid, expected_pid, "PID should match current process");
375375
}
376-
376+
377377
#[test]
378378
fn test_unique_session_ids() {
379379
let pty1 = ShaiPtyManager::new().unwrap();
380380
thread::sleep(Duration::from_millis(1)); // Ensure different timestamp
381381
let pty2 = ShaiPtyManager::new().unwrap();
382-
382+
383383
assert_ne!(pty1.get_session_id(), pty2.get_session_id());
384384
}
385385

386386
#[test]
387387
fn test_create_pty_pair() {
388388
let result = ShaiPtyManager::create_pty_pair();
389389
assert!(result.is_ok());
390-
390+
391391
let (master_fd, slave_fd) = result.unwrap();
392-
392+
393393
// Valid file descriptors
394394
assert!(master_fd >= 0);
395395
assert!(slave_fd >= 0);
396396
assert_ne!(master_fd, slave_fd);
397-
397+
398398
// Clean up
399399
unsafe {
400400
libc::close(master_fd);
@@ -405,23 +405,23 @@ mod tests {
405405
#[test]
406406
fn test_pty_pair_communication() {
407407
let (master_fd, slave_fd) = ShaiPtyManager::create_pty_pair().unwrap();
408-
408+
409409
// Write to master, should be readable from slave
410410
let test_data = b"Hello PTY\n";
411411
let bytes_written = unsafe {
412412
libc::write(master_fd, test_data.as_ptr() as *const libc::c_void, test_data.len())
413413
};
414414
assert_eq!(bytes_written, test_data.len() as isize);
415-
415+
416416
// Read from slave
417417
let mut buffer = [0u8; 64];
418418
let bytes_read = unsafe {
419419
libc::read(slave_fd, buffer.as_mut_ptr() as *mut libc::c_void, buffer.len())
420420
};
421-
421+
422422
assert!(bytes_read > 0);
423423
assert_eq!(&buffer[..bytes_read as usize], test_data);
424-
424+
425425
// Clean up
426426
unsafe {
427427
libc::close(master_fd);
@@ -432,21 +432,21 @@ mod tests {
432432
#[test]
433433
fn test_multiple_pty_creation() {
434434
let mut ptys = Vec::new();
435-
435+
436436
// Create multiple PTYs
437437
for _ in 0..5 {
438438
let pty = ShaiPtyManager::new().unwrap();
439439
ptys.push(pty);
440440
}
441-
441+
442442
// All should have unique session IDs
443443
let session_ids: Vec<String> = ptys.iter().map(|p| p.get_session_id().to_string()).collect();
444444
let mut unique_ids = session_ids.clone();
445445
unique_ids.sort();
446446
unique_ids.dedup();
447-
447+
448448
assert_eq!(session_ids.len(), unique_ids.len());
449-
449+
450450
for pty in &ptys {
451451
assert!(pty.master_fd >= 0);
452452
assert!(pty.slave_fd >= 0);

0 commit comments

Comments
 (0)