Преглед на файлове

Add tty line support

Not always is desirable to create a pseudo terminal, and some times
we want to open a terminal emulator over a tty line. With this new
patch is possible to do someting like:

	$ st -l /dev/ttyS0 115200

Without this option was needed to launch another terminal emulator
over st (for example minicom, picocom, cu, ...).
Roberto E. Vargas Caballero преди 10 години
родител
ревизия
215bdb2da3
променени са 3 файла, в които са добавени 91 реда и са изтрити 13 реда
  1. 1 0
      config.def.h
  2. 36 1
      st.1
  3. 54 12
      st.c

+ 1 - 0
config.def.h

@@ -9,6 +9,7 @@ static char font[] = "Liberation Mono:pixelsize=12:antialias=false:autohint=fals
 static int borderpx = 2;
 static char shell[] = "/bin/sh";
 static char *utmp = NULL;
+static char stty_args[] = "stty raw -echo -iexten echonl";
 
 /* identification sequence returned in DA and DECID */
 static char vtiden[] = "\033[?6c";

+ 36 - 1
st.1

@@ -15,11 +15,36 @@ st \- simple terminal
 .IR file ]
 .RB [ \-t 
 .IR title ]
+.RB [ \-l
+.IR line ]
 .RB [ \-w 
 .IR windowid ]
 .RB [ \-v ]
 .RB [ \-e
 .IR command ...]
+.RI [ commands ...]
+.PP
+.B st
+.RB [ \-a ]
+.RB [ \-c
+.IR class ]
+.RB [ \-f
+.IR font ]
+.RB [ \-g
+.IR geometry ]
+.RB [ \-i ]
+.RB [ \-o
+.IR file ]
+.RB [ \-t
+.IR title ]
+.RB [ \-l
+.IR line ]
+.RB [ \-w
+.IR windowid ]
+.RB [ \-v ]
+.RB [ \-l
+.IR line ]
+.RI [ stty_args ...]
 .SH DESCRIPTION
 .B st
 is a simple terminal emulator.
@@ -58,6 +83,11 @@ defines the window title (default 'st').
 embeds st within the window identified by 
 .I windowid
 .TP
+.BI \-l " line"
+use a tty line instead of a pseudo terminal.
+When this flag is used
+remaining arguments are used as flags for stty.
+.TP
 .B \-v
 prints version information to stderr, then exits.
 .TP
@@ -67,6 +97,9 @@ st executes
 instead of the shell.  If this is used it
 .B must be the last option
 on the command line, as in xterm / rxvt.
+This option is only intended for compability,
+and all the remaining arguments are used as a command
+even without it.
 .SH SHORTCUTS
 .TP
 .B Ctrl-Print Screen
@@ -110,7 +143,9 @@ See the LICENSE file for the authors.
 .SH LICENSE
 See the LICENSE file for the terms of redistribution.
 .SH SEE ALSO
-.BR tabbed (1)
+.BR tabbed (1),
+.BR utmp (1),
+.BR stty (1)
 .SH BUGS
 See the TODO file in the distribution.
 

+ 54 - 12
st.c

@@ -352,6 +352,7 @@ static void draw(void);
 static void redraw(void);
 static void drawregion(int, int, int, int);
 static void execsh(void);
+static void stty(void);
 static void sigchld(int);
 static void run(void);
 
@@ -508,6 +509,7 @@ static char *opt_title = NULL;
 static char *opt_embed = NULL;
 static char *opt_class = NULL;
 static char *opt_font = NULL;
+static char *opt_line = NULL;
 static int oldbutton = 3; /* button event on startup: 3 = release */
 
 static char *usedfont = NULL;
@@ -1253,11 +1255,55 @@ sigchld(int a) {
 	exit(EXIT_SUCCESS);
 }
 
+
+void
+stty(void)
+{
+	char cmd[_POSIX_ARG_MAX], **p, *q, *s;
+	size_t n, siz;
+
+	if((n = strlen(stty_args)) > sizeof(cmd)-1)
+		die("incorrect stty parameters\n");
+	memcpy(cmd, stty_args, n);
+	q = cmd + n;
+	siz = sizeof(cmd) - n;
+	for(p = opt_cmd; p && (s = *p); ++p) {
+		if((n = strlen(s)) > siz-1)
+			die("stty parameter length too long\n");
+		*q++ = ' ';
+		q = memcpy(q, s, n);
+		q += n;
+		siz-= n + 1;
+	}
+	*q = '\0';
+	system(cmd);
+}
+
 void
 ttynew(void) {
 	int m, s;
 	struct winsize w = {term.row, term.col, 0, 0};
 
+	if(opt_io) {
+		term.mode |= MODE_PRINT;
+		iofd = (!strcmp(opt_io, "-")) ?
+			  STDOUT_FILENO :
+			  open(opt_io, O_WRONLY | O_CREAT, 0666);
+		if(iofd < 0) {
+			fprintf(stderr, "Error opening %s:%s\n",
+				opt_io, strerror(errno));
+		}
+	}
+
+	if (opt_line) {
+		if((cmdfd = open(opt_line, O_RDWR)) < 0)
+			die("open line failed: %s\n", strerror(errno));
+		close(STDIN_FILENO);
+		dup(cmdfd);
+		stty();
+		return;
+	}
+
 	/* seems to work fine on linux, openbsd and freebsd */
 	if(openpty(&m, &s, NULL, NULL, &w) < 0)
 		die("openpty failed: %s\n", strerror(errno));
@@ -1267,6 +1313,7 @@ ttynew(void) {
 		die("fork failed\n");
 		break;
 	case 0:
+		close(iofd);
 		setsid(); /* create a new process group */
 		dup2(s, STDIN_FILENO);
 		dup2(s, STDOUT_FILENO);
@@ -1281,16 +1328,6 @@ ttynew(void) {
 		close(s);
 		cmdfd = m;
 		signal(SIGCHLD, sigchld);
-		if(opt_io) {
-			term.mode |= MODE_PRINT;
-			iofd = (!strcmp(opt_io, "-")) ?
-				  STDOUT_FILENO :
-				  open(opt_io, O_WRONLY | O_CREAT, 0666);
-			if(iofd < 0) {
-				fprintf(stderr, "Error opening %s:%s\n",
-					opt_io, strerror(errno));
-			}
-		}
 		break;
 	}
 }
@@ -4009,9 +4046,11 @@ run(void) {
 
 void
 usage(void) {
-	die("%s " VERSION " (c) 2010-2015 st engineers\n" \
+	die("%s " VERSION " (c) 2010-2015 st engineers\n"
 	"usage: st [-a] [-v] [-c class] [-f font] [-g geometry] [-o file]\n"
-	"          [-i] [-t title] [-w windowid] [-e command ...] [command ...]\n",
+	"          [-i] [-t title] [-w windowid] [-e command ...] [command ...]\n"
+	"       st [-a] [-v] [-c class] [-f font] [-g geometry] [-o file]\n"
+	"          [-i] [-t title] [-w windowid] [-l line] [stty_args ...]\n",
 	argv0);
 }
 
@@ -4047,6 +4086,9 @@ main(int argc, char *argv[]) {
 	case 'o':
 		opt_io = EARGF(usage());
 		break;
+	case 'l':
+		opt_line = EARGF(usage());
+		break;
 	case 't':
 		opt_title = EARGF(usage());
 		break;