1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
|
* If a "--" argument is encountered on bterm's command line, terminate
option processing there and accept arguments after the command name.
Thanks to Colin Watson <cjwatson@ubuntu.com> for the patch.
Closes: #528783.
diff --git a/bterm.c b/bterm.c
index bf2ef7b..d7b574f 100644
--- a/bterm.c
+++ b/bterm.c
@@ -66,6 +66,26 @@ static int child_pid = 0;
static struct termios ttysave;
static int quit = 0;
+/* Out of memory. Give up. */
+static void out_of_memory (void)
+{
+ fprintf (stderr, "virtual memory exhausted\n");
+ abort ();
+}
+
+/* Allocate AMT bytes of memory and make sure it succeeded. */
+static void *xmalloc (size_t size)
+{
+ void *p;
+
+ if (size == 0)
+ return 0;
+ p = malloc (size);
+ if (!p)
+ out_of_memory ();
+ return p;
+}
+
/* This first tries the modern Unix98 way of getting a pty, followed by the
* old-fashioned BSD way in case that fails. */
int get_ptytty(int *xptyfd, int *xttyfd)
@@ -145,7 +165,7 @@ void sigterm(int sig)
quit = 1;
}
-void spawn_shell(int ptyfd, int ttyfd, const char *command)
+void spawn_shell(int ptyfd, int ttyfd, char * const *command_args)
{
fflush(stdout);
child_pid = fork();
@@ -170,7 +190,7 @@ void spawn_shell(int ptyfd, int ttyfd, const char *command)
setgid(getgid());
setuid(getuid());
- execl(command, command, NULL);
+ execvp(command_args[0], command_args);
exit(127);
}
@@ -224,11 +244,13 @@ int main(int argc, char *argv[])
int ptyfd, ttyfd;
struct bogl_font *font;
char *locale = "", *command = NULL;
+ char **command_args;
int i;
char o = ' ';
int pending = 0;
- for (i = 1 ; i < argc ; ++i)
+ for (i = 1 ; i < argc ; ++i) {
+ int done = 0;
if (argv[i][0] == '-')
switch (argv[i][1])
{
@@ -237,6 +259,10 @@ int main(int argc, char *argv[])
o = argv[i][1];
break;
+ case '-':
+ done = 1;
+ break;
+
default:
printf ("unknown option: %c\n", argv[i][1]);
}
@@ -258,6 +284,10 @@ int main(int argc, char *argv[])
break;
}
+ if (done)
+ break;
+ }
+
setlocale(LC_CTYPE, locale);
if (font_name == NULL) {
@@ -291,7 +321,22 @@ int main(int argc, char *argv[])
exit(1);
}
- spawn_shell(ptyfd, ttyfd, command == NULL ? "/bin/sh" : command);
+ if (command) {
+ command_args = xmalloc(2 * sizeof *command_args);
+ command_args[0] = command;
+ command_args[1] = NULL;
+ } else if (i < argc - 1) {
+ int j;
+ command_args = xmalloc((argc - i) * sizeof *command_args);
+ for (j = i + 1; j < argc; ++j)
+ command_args[j - (i + 1)] = argv[j];
+ command_args[argc - (i + 1)] = NULL;
+ } else {
+ command_args = xmalloc(2 * sizeof *command_args);
+ command_args[0] = "/bin/sh";
+ command_args[1] = NULL;
+ }
+ spawn_shell(ptyfd, ttyfd, command_args);
signal(SIGHUP, reload_font);
signal(SIGTERM, sigterm);
|