diff --git a/config.def.h b/config.def.h
index 616616a..82b1b09 100644
--- a/config.def.h
+++ b/config.def.h
@@ -16,7 +16,7 @@ static int borderpx = 2;
  * 4: value of shell in /etc/passwd
  * 5: value of shell in config.h
  */
-char *shell = "/bin/sh";
+static char *shell = "/bin/sh";
 char *utmp = NULL;
 char *stty_args = "stty raw pass8 nl -echo -iexten -cstopb 38400";
 
diff --git a/st.c b/st.c
index da832ed..ce32cc0 100644
--- a/st.c
+++ b/st.c
@@ -136,8 +136,7 @@ typedef struct {
 	int narg;              /* nb of args */
 } STREscape;
 
-
-static void execsh(char **);
+static void execsh(char *, char **);
 static void stty(char **);
 static void sigchld(int);
 static void ttywriteraw(const char *, size_t);
@@ -201,15 +200,13 @@ static char *base64dec(const char *);
 static ssize_t xwrite(int, const char *, size_t);
 
 /* Globals */
-int cmdfd;
-pid_t pid;
-int oldbutton   = 3; /* button event on startup: 3 = release */
-
 static Term term;
 static Selection sel;
 static CSIEscape csiescseq;
 static STREscape strescseq;
 static int iofd = 1;
+static int cmdfd;
+static pid_t pid;
 
 static uchar utfbyte[UTF_SIZ + 1] = {0x80,    0, 0xC0, 0xE0, 0xF0};
 static uchar utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
@@ -659,7 +656,7 @@ die(const char *errstr, ...)
 }
 
 void
-execsh(char **args)
+execsh(char *cmd, char **args)
 {
 	char *sh, *prog;
 	const struct passwd *pw;
@@ -673,7 +670,7 @@ execsh(char **args)
 	}
 
 	if ((sh = getenv("SHELL")) == NULL)
-		sh = (pw->pw_shell[0]) ? pw->pw_shell : shell;
+		sh = (pw->pw_shell[0]) ? pw->pw_shell : cmd;
 
 	if (args)
 		prog = args[0];
@@ -745,8 +742,8 @@ stty(char **args)
 	    perror("Couldn't call stty");
 }
 
-void
-ttynew(char *line, char *out, char **args)
+int
+ttynew(char *line, char *cmd, char *out, char **args)
 {
 	int m, s;
 
@@ -765,7 +762,7 @@ ttynew(char *line, char *out, char **args)
 			die("open line failed: %s\n", strerror(errno));
 		dup2(cmdfd, 0);
 		stty(args);
-		return;
+		return cmdfd;
 	}
 
 	/* seems to work fine on linux, openbsd and freebsd */
@@ -786,7 +783,7 @@ ttynew(char *line, char *out, char **args)
 			die("ioctl TIOCSCTTY failed: %s\n", strerror(errno));
 		close(s);
 		close(m);
-		execsh(args);
+		execsh(cmd, args);
 		break;
 	default:
 		close(s);
@@ -794,6 +791,7 @@ ttynew(char *line, char *out, char **args)
 		signal(SIGCHLD, sigchld);
 		break;
 	}
+	return cmdfd;
 }
 
 size_t
@@ -916,6 +914,13 @@ ttyresize(int tw, int th)
 		fprintf(stderr, "Couldn't set window size: %s\n", strerror(errno));
 }
 
+void
+ttyhangup()
+{
+	/* Send SIGHUP to shell */
+	kill(pid, SIGHUP);
+}
+
 int
 tattrset(int attr)
 {
diff --git a/st.h b/st.h
index b5bc1b5..0a7472b 100644
--- a/st.h
+++ b/st.h
@@ -125,7 +125,8 @@ int tattrset(int);
 void tnew(int, int);
 void tresize(int, int);
 void tsetdirtattr(int);
-void ttynew(char *, char *, char **);
+void ttyhangup(void);
+int ttynew(char *, char *, char *, char **);
 size_t ttyread(void);
 void ttyresize(int, int);
 void ttywrite(const char *, size_t, int);
@@ -147,13 +148,7 @@ void *xmalloc(size_t);
 void *xrealloc(void *, size_t);
 char *xstrdup(char *);
 
-/* Globals */
-extern int cmdfd;
-extern pid_t pid;
-extern int oldbutton;
-
 /* config.h globals */
-extern char *shell;
 extern char *utmp;
 extern char *stty_args;
 extern char *vtiden;
diff --git a/x.c b/x.c
index 873ff08..970d6dd 100644
--- a/x.c
+++ b/x.c
@@ -227,6 +227,8 @@ static char *opt_line  = NULL;
 static char *opt_name  = NULL;
 static char *opt_title = NULL;
 
+static int oldbutton = 3; /* button event on startup: 3 = release */
+
 void
 clipcopy(const Arg *dummy)
 {
@@ -1733,8 +1735,7 @@ cmessage(XEvent *e)
 			win.mode &= ~MODE_FOCUSED;
 		}
 	} else if (e->xclient.data.l[0] == xw.wmdeletewin) {
-		/* Send SIGHUP to shell */
-		kill(pid, SIGHUP);
+		ttyhangup();
 		exit(0);
 	}
 }
@@ -1755,6 +1756,7 @@ run(void)
 	int w = win.w, h = win.h;
 	fd_set rfd;
 	int xfd = XConnectionNumber(xw.dpy), xev, blinkset = 0, dodraw = 0;
+	int ttyfd;
 	struct timespec drawtimeout, *tv = NULL, now, last, lastblink;
 	long deltatime;
 
@@ -1774,7 +1776,7 @@ run(void)
 		}
 	} while (ev.type != MapNotify);
 
-	ttynew(opt_line, opt_io, opt_cmd);
+	ttyfd = ttynew(opt_line, shell, opt_io, opt_cmd);
 	cresize(w, h);
 
 	clock_gettime(CLOCK_MONOTONIC, &last);
@@ -1782,15 +1784,15 @@ run(void)
 
 	for (xev = actionfps;;) {
 		FD_ZERO(&rfd);
-		FD_SET(cmdfd, &rfd);
+		FD_SET(ttyfd, &rfd);
 		FD_SET(xfd, &rfd);
 
-		if (pselect(MAX(xfd, cmdfd)+1, &rfd, NULL, NULL, tv, NULL) < 0) {
+		if (pselect(MAX(xfd, ttyfd)+1, &rfd, NULL, NULL, tv, NULL) < 0) {
 			if (errno == EINTR)
 				continue;
 			die("select failed: %s\n", strerror(errno));
 		}
-		if (FD_ISSET(cmdfd, &rfd)) {
+		if (FD_ISSET(ttyfd, &rfd)) {
 			ttyread();
 			if (blinktimeout) {
 				blinkset = tattrset(ATTR_BLINK);
@@ -1834,7 +1836,7 @@ run(void)
 
 			if (xev && !FD_ISSET(xfd, &rfd))
 				xev--;
-			if (!FD_ISSET(cmdfd, &rfd) && !FD_ISSET(xfd, &rfd)) {
+			if (!FD_ISSET(ttyfd, &rfd) && !FD_ISSET(xfd, &rfd)) {
 				if (blinkset) {
 					if (TIMEDIFF(now, lastblink) \
 							> blinktimeout) {