/* macros */
 #define NUMMAXLEN(x)           ((int)(sizeof(x) * 2.56 + 0.5) + 1)
-#define DEFAULT(a, b)          (a) = (a) ? (a) : (b)
 #define ISCONTROLC0(c)         (BETWEEN(c, 0, 0x1f) || (c) == '\177')
 #define ISCONTROLC1(c)         (BETWEEN(c, 0x80, 0x9f))
 #define ISCONTROL(c)           (ISCONTROLC0(c) || ISCONTROLC1(c))
 /* config.h for applying patches and the configuration. */
 #include "config.h"
 
-static void execsh(void);
-static void stty(void);
+static void execsh(char **);
+static void stty(char **);
 static void sigchld(int);
 
 static void csidump(void);
 Selection sel;
 int cmdfd;
 pid_t pid;
-char **opt_cmd  = NULL;
-char *opt_class = NULL;
-char *opt_embed = NULL;
-char *opt_font  = NULL;
-char *opt_io    = NULL;
-char *opt_line  = NULL;
-char *opt_name  = NULL;
-char *opt_title = NULL;
 int oldbutton   = 3; /* button event on startup: 3 = release */
 
 static CSIEscape csiescseq;
 }
 
 void
-execsh(void)
+execsh(char **args)
 {
-       char **args, *sh, *prog;
+       char *sh, *prog;
        const struct passwd *pw;
 
        errno = 0;
        if ((sh = getenv("SHELL")) == NULL)
                sh = (pw->pw_shell[0]) ? pw->pw_shell : shell;
 
-       if (opt_cmd)
-               prog = opt_cmd[0];
+       if (args)
+               prog = args[0];
        else if (utmp)
                prog = utmp;
        else
                prog = sh;
-       args = (opt_cmd) ? opt_cmd : (char *[]) {prog, NULL};
+       DEFAULT(args, ((char *[]) {prog, NULL}));
 
        unsetenv("COLUMNS");
        unsetenv("LINES");
 
 
 void
-stty(void)
+stty(char **args)
 {
        char cmd[_POSIX_ARG_MAX], **p, *q, *s;
        size_t n, siz;
        memcpy(cmd, stty_args, n);
        q = cmd + n;
        siz = sizeof(cmd) - n;
-       for (p = opt_cmd; p && (s = *p); ++p) {
+       for (p = args; p && (s = *p); ++p) {
                if ((n = strlen(s)) > siz-1)
                        die("stty parameter length too long\n");
                *q++ = ' ';
 }
 
 void
-ttynew(void)
+ttynew(char *line, char *out, char **args)
 {
        int m, s;
        struct winsize w = {term.row, term.col, 0, 0};
 
-       if (opt_io) {
+       if (out) {
                term.mode |= MODE_PRINT;
-               iofd = (!strcmp(opt_io, "-")) ?
-                         1 : open(opt_io, O_WRONLY | O_CREAT, 0666);
+               iofd = (!strcmp(out, "-")) ?
+                         1 : open(out, O_WRONLY | O_CREAT, 0666);
                if (iofd < 0) {
                        fprintf(stderr, "Error opening %s:%s\n",
-                               opt_io, strerror(errno));
+                               out, strerror(errno));
                }
        }
 
-       if (opt_line) {
-               if ((cmdfd = open(opt_line, O_RDWR)) < 0)
+       if (line) {
+               if ((cmdfd = open(line, O_RDWR)) < 0)
                        die("open line failed: %s\n", strerror(errno));
                dup2(cmdfd, 0);
-               stty();
+               stty(args);
                return;
        }
 
                        die("ioctl TIOCSCTTY failed: %s\n", strerror(errno));
                close(s);
                close(m);
-               execsh();
+               execsh(args);
                break;
        default:
                close(s);
 tprinter(char *s, size_t len)
 {
        if (iofd != -1 && xwrite(iofd, s, len) < 0) {
-               fprintf(stderr, "Error writing in %s:%s\n",
-                       opt_io, strerror(errno));
+               perror("Error writing to output file");
                close(iofd);
                iofd = -1;
        }
 void
 resettitle(void)
 {
-       xsettitle(opt_title ? opt_title : "st");
+       xsettitle(NULL);
 }
 
 void
 
 #define LEN(a)                 (sizeof(a) / sizeof(a)[0])
 #define BETWEEN(x, a, b)       ((a) <= (x) && (x) <= (b))
 #define DIVCEIL(n, d)          (((n) + ((d) - 1)) / (d))
+#define DEFAULT(a, b)          (a) = (a) ? (a) : (b)
 #define LIMIT(x, a, b)         (x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x)
 #define ATTRCMP(a, b)          ((a).mode != (b).mode || (a).fg != (b).fg || \
                                (a).bg != (b).bg)
 void tresize(int, int);
 void tsetdirt(int, int);
 void tsetdirtattr(int);
-void ttynew(void);
+void ttynew(char *, char *, char **);
 size_t ttyread(void);
 void ttyresize(int, int);
 void ttysend(char *, size_t);
 extern Selection sel;
 extern int cmdfd;
 extern pid_t pid;
-extern char **opt_cmd;
-extern char *opt_class;
-extern char *opt_embed;
-extern char *opt_font;
-extern char *opt_io;
-extern char *opt_line;
-extern char *opt_name;
-extern char *opt_title;
 extern int oldbutton;
 
 /* config.h globals */
 
 static double usedfontsize = 0;
 static double defaultfontsize = 0;
 
+static char *opt_class = NULL;
+static char **opt_cmd  = NULL;
+static char *opt_embed = NULL;
+static char *opt_font  = NULL;
+static char *opt_io    = NULL;
+static char *opt_line  = NULL;
+static char *opt_name  = NULL;
+static char *opt_title = NULL;
+
 void
 zoom(const Arg *arg)
 {
 xsettitle(char *p)
 {
        XTextProperty prop;
+       DEFAULT(p, "st");
 
        Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle,
                        &prop);
        } while (ev.type != MapNotify);
 
        cresize(w, h);
-       ttynew();
+       ttynew(opt_line, opt_io, opt_cmd);
        ttyresize(win.tw, win.th);
 
        clock_gettime(CLOCK_MONOTONIC, &last);