Finished design touchups

Mikayla Maki created

Change summary

Cargo.lock                        |  1 
crates/terminal/Cargo.toml        |  2 
crates/terminal/src/connection.rs | 87 ++++++++++++++++++++++++++++++++
3 files changed, 89 insertions(+), 1 deletion(-)

Detailed changes

Cargo.lock 🔗

@@ -5361,6 +5361,7 @@ dependencies = [
  "futures",
  "gpui",
  "itertools",
+ "libc",
  "mio-extras",
  "ordered-float",
  "project",

crates/terminal/Cargo.toml 🔗

@@ -23,6 +23,8 @@ ordered-float = "2.1.1"
 itertools = "0.10"
 dirs = "4.0.0"
 shellexpand = "2.1.0"
+libc = "0.2"
+
 
 [dev-dependencies]
 gpui = { path = "../gpui", features = ["test-support"] }

crates/terminal/src/connection.rs 🔗

@@ -117,6 +117,13 @@ impl TerminalConnection {
             }
         };
 
+        let shell = {
+            let mut buf = [0; 1024];
+            let pw = alacritty_unix::get_pw_entry(&mut buf).unwrap();
+            pw.shell.to_string()
+            // alacritty_unix::default_shell(&pw)
+        };
+
         //And connect them together
         let event_loop = EventLoop::new(
             term.clone(),
@@ -149,7 +156,7 @@ impl TerminalConnection {
         TerminalConnection {
             pty_tx: Notifier(pty_tx),
             term,
-            title: DEFAULT_TITLE.to_string(),
+            title: shell.to_string(),
             associated_directory: working_directory,
         }
     }
@@ -261,3 +268,81 @@ impl Drop for TerminalConnection {
 impl Entity for TerminalConnection {
     type Event = Event;
 }
+
+mod alacritty_unix {
+    use alacritty_terminal::config::Program;
+    use gpui::anyhow::{bail, Result};
+    use libc::{self};
+    use std::ffi::CStr;
+    use std::mem::MaybeUninit;
+    use std::ptr;
+
+    #[derive(Debug)]
+    pub struct Passwd<'a> {
+        _name: &'a str,
+        _dir: &'a str,
+        pub shell: &'a str,
+    }
+
+    /// Return a Passwd struct with pointers into the provided buf.
+    ///
+    /// # Unsafety
+    ///
+    /// If `buf` is changed while `Passwd` is alive, bad thing will almost certainly happen.
+    pub fn get_pw_entry(buf: &mut [i8; 1024]) -> Result<Passwd<'_>> {
+        // Create zeroed passwd struct.
+        let mut entry: MaybeUninit<libc::passwd> = MaybeUninit::uninit();
+
+        let mut res: *mut libc::passwd = ptr::null_mut();
+
+        // Try and read the pw file.
+        let uid = unsafe { libc::getuid() };
+        let status = unsafe {
+            libc::getpwuid_r(
+                uid,
+                entry.as_mut_ptr(),
+                buf.as_mut_ptr() as *mut _,
+                buf.len(),
+                &mut res,
+            )
+        };
+        let entry = unsafe { entry.assume_init() };
+
+        if status < 0 {
+            bail!("getpwuid_r failed");
+        }
+
+        if res.is_null() {
+            bail!("pw not found");
+        }
+
+        // Sanity check.
+        assert_eq!(entry.pw_uid, uid);
+
+        // Build a borrowed Passwd struct.
+        Ok(Passwd {
+            _name: unsafe { CStr::from_ptr(entry.pw_name).to_str().unwrap() },
+            _dir: unsafe { CStr::from_ptr(entry.pw_dir).to_str().unwrap() },
+            shell: unsafe { CStr::from_ptr(entry.pw_shell).to_str().unwrap() },
+        })
+    }
+
+    #[cfg(target_os = "macos")]
+    pub fn _default_shell(pw: &Passwd<'_>) -> Program {
+        let shell_name = pw.shell.rsplit('/').next().unwrap();
+        let argv = vec![
+            String::from("-c"),
+            format!("exec -a -{} {}", shell_name, pw.shell),
+        ];
+
+        Program::WithArgs {
+            program: "/bin/bash".to_owned(),
+            args: argv,
+        }
+    }
+
+    #[cfg(not(target_os = "macos"))]
+    pub fn default_shell(pw: &Passwd<'_>) -> Program {
+        Program::Just(env::var("SHELL").unwrap_or_else(|_| pw.shell.to_owned()))
+    }
+}