So, apparently the chrome/geckodriver processes will terminate on their own if the user sends ctrl+c to the console. It will not terminate on its own if the program finishes running naturally.

If you’re interested in terminating it on your own, like I also was, here is how I went about it.

use std::process::{Child, Command};

fn main() {
	let mut s = Server::default();
	s.start();
	s.shutdown();
}

struct Server {
	child: Option<Child>
}

impl Default for Server {
	fn default() -> Self {
		Self {
			child: None
		}
	}
}

impl Server {
	fn start(&mut self) {
		self.child = Some(Command::new("./chromedriver")
			.spawn()
			.expect("ls command failed to start"));
	}

	fn shutdown(&mut self) {
		input(None); // wait for input so you can observe the process
		self.child.as_mut().unwrap().kill();
		self.child.as_mut().unwrap().wait();
		println!("shutdown");
	}
}

pub fn input(prompt: Option<String>) {
	let mut input = String::new();
	match prompt {
		Some(prompt) => println!("{}", prompt),
		None => ()
	}
	io::stdin().read_line(&mut input).expect("Failed to read input");
}