commit 9a49b5fe634dad242bf637d99902abea6ff81c72
parent 3bf4efd89a43d94ad46bdda31137a3bc9404ed8c
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Fri, 24 Oct 2014 21:37:33 +0000
remove -i and -l flag
it is now possible to do: printf 'bla' | sob, this will be used as the
initial input. the input will be handled like actual input so escape
codes work too (this is a feature).
Diffstat:
M | sob.1 | | | 5 | ----- |
M | sob.c | | | 70 | ++++++++++++++++++++++++++++++++++++++++++++++++++-------------------- |
2 files changed, 50 insertions(+), 25 deletions(-)
diff --git a/sob.1 b/sob.1
@@ -3,17 +3,12 @@
sob \- simple output bar
.SH SYNOPSIS
.B sob
-.RB [ \-l
-.IR line ]
.RB [ \-p
.IR prompt ]
.SH DESCRIPTION
sob is a simple line editor.
.SH OPTIONS
.TP
-.B \-i " input"
-initial input on line, this can include escape codes which will be handled.
-.TP
.B \-p " prompt"
prompt string.
.SH BUGS
diff --git a/sob.c b/sob.c
@@ -70,6 +70,7 @@ static void cleanup(void);
static void clear(void);
static void gettermsize(void);
static void handleinput(const unsigned char *, size_t);
+static void initialinput(void);
static void resize(void);
static int run(void);
static void setup(void);
@@ -754,8 +755,6 @@ sighandler(int signum)
static void
setup(void)
{
- struct sigaction sa;
-
tcgetattr(STDIN_FILENO, &ttystate);
ttysave = ttystate;
/* turn off canonical mode and echo */
@@ -766,16 +765,6 @@ setup(void)
tcsetattr(STDIN_FILENO, TCSANOW, &ttystate);
/* get terminal window size */
gettermsize();
-
- /* clear screen */
- clear();
-
- /* signal handling */
- memset(&sa, 0, sizeof(sa));
- sa.sa_flags = SA_RESTART;
- sa.sa_handler = sighandler;
- sigaction(SIGTERM, &sa, NULL);
- sigaction(SIGWINCH, &sa, NULL);
}
static void
@@ -855,8 +844,8 @@ run(void)
unsigned char buf[BUFSIZ];
if(isrunning) {
- line_draw();
fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK);
+ line_draw();
}
while(isrunning) {
FD_ZERO(&fdr);
@@ -892,7 +881,7 @@ fini:
static void
usage(void)
{
- fprintf(stderr, "usage: %s [-i input] [-p prompt]\n", argv0);
+ fprintf(stderr, "usage: %s [-p prompt]\n", argv0);
exit(EXIT_FAILURE);
}
@@ -904,15 +893,38 @@ clear(void)
fflush(outfp);
}
+static void
+initialinput(void)
+{
+ unsigned char buf[BUFSIZ];
+ int fd, r;
+
+ /* read initial input from stdin */
+ fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK);
+ while(1) {
+ if((r = readfd(STDIN_FILENO, (char *)buf, sizeof(buf))) <= 0)
+ break;
+ buf[r] = '\0';
+ handleinput(buf, r);
+ }
+ /* close and reattach to stdin */
+ close(STDIN_FILENO);
+ if((fd = open("/dev/tty", O_RDONLY | O_NONBLOCK)) == -1) {
+ fprintf(stderr, "open: /dev/tty: %s\n", strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ if(dup2(fd, STDIN_FILENO) == -1) {
+ fprintf(stderr, "dup2: /dev/tty: %s\n", strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+}
+
int
main(int argc, char **argv)
{
- char *input = NULL;
+ struct sigaction sa;
ARGBEGIN {
- case 'i':
- input = EARGF(usage());
- break;
case 'p':
prompt = EARGF(usage());
break;
@@ -924,8 +936,26 @@ main(int argc, char **argv)
outfp = stderr;
setlocale(LC_ALL, "");
setup();
- if(input)
- handleinput((unsigned char *)input, strlen(input));
+
+ /* signal handling */
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_flags = SA_RESTART;
+ sa.sa_handler = sighandler;
+ sigaction(SIGTERM, &sa, NULL);
+ sigaction(SIGWINCH, &sa, NULL);
+ /* reap zombie childs >=) */
+ sa.sa_handler = SIG_IGN;
+ sigaction(SIGCHLD, &sa, NULL);
+
+ if(!isatty(STDIN_FILENO)) {
+ initialinput();
+ /* setup tty again because we (re)open "/dev/tty" */
+ setup();
+ }
+
+ /* clear screen */
+ clear();
+
run();
cleanup();