summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Ankarström <john@ankarstrom.se>2021-06-07 16:36:05 +0200
committerJohn Ankarström <john@ankarstrom.se>2021-06-08 01:50:54 +0200
commit7aaf4f2423e2bcabce508e91255de673db50b728 (patch)
treecfdfc247185d7a97fce6f96110fb964f00b766fe
parent60b250c267e9ce69f428fd2f0f56a4b1a54f2004 (diff)
downloadksh-master.tar.gz
Add [-w write-file] optionHEADmaster
ksh will write lines to write-file containing information about the status of the shell: after prompt: empty line after command entry: "cmd" followed by command after cwd change: "cwd" followed by new cwd fg is handled specially, printing a new "cmd" line with the original command associated with the job.
-rw-r--r--jobs.c7
-rw-r--r--ksh.Man7
-rw-r--r--main.c12
-rw-r--r--misc.c12
-rw-r--r--path.c2
-rw-r--r--sh.h1
6 files changed, 38 insertions, 3 deletions
diff --git a/jobs.c b/jobs.c
index c8cc781..65c364f 100644
--- a/jobs.c
+++ b/jobs.c
@@ -840,6 +840,8 @@ j_resume(cp, bg)
shprintf("[%d] ", j->job);
running = 0;
+ if (writefd)
+ dprintf(writefd, "cmd");
for (p = j->proc_list; p != (Proc *) 0; p = p->next) {
if (p->state == PSTOPPED) {
p->state = PRUNNING;
@@ -847,9 +849,14 @@ j_resume(cp, bg)
running = 1;
}
shprintf("%s%s", p->command, p->next ? "| " : null);
+ if (writefd)
+ dprintf(writefd, "%s%s",
+ p->command, p->next ? "| " : null);
}
shprintf("%s", newline);
shf_flush(shl_stdout);
+ if (writefd)
+ dprintf(writefd, "\n");
if (running)
j->state = PRUNNING;
diff --git a/ksh.Man b/ksh.Man
index 69ea1f0..80ad538 100644
--- a/ksh.Man
+++ b/ksh.Man
@@ -43,7 +43,7 @@ sh \- Public domain Bourne shell
.sh(
\fBsh\fP
.sh)
-[\fB\(+-abCefhiklmnprsuvxX\fP] [\fB\(+-o\fP \fIoption\fP] [ [ \fB\-c\fP \fIcommand-string\fP [\fIcommand-name\fP] | \fB\-s\fP | \fIfile\fP ] [\fIargument\fP ...] ]
+[\fB\(+-abCefhiklmnprsuvxX\fP] [\fB\(+-o\fP \fIoption\fP] [\fB-w\fP \fIwrite-file\fP]] [ [ \fB\-c\fP \fIcommand-string\fP [\fIcommand-name\fP] | \fB\-s\fP | \fIfile\fP ] [\fIargument\fP ...] ]
.ad b
.\"}}}
.\"{{{ Description
@@ -72,6 +72,11 @@ the shell reads commands from standard input; all non-option arguments
are positional parameters
.IP \fB\-r\fP
restricted mode \(em see below
+.IP "\fB\-w\fP \fIwrite-file\fP"
+the shell writes to \fIwrite-file\fR an empty line after each
+prompt, a line beginning with \fIcwd\fR after each directory change
+and a line beginning with \fIcmd\fR after each interactive command
+entry.
.PP
In addition to the above, the options described in the \fBset\fP built-in
command can also be used on the command line.
diff --git a/main.c b/main.c
index 41d4d80..dad50d3 100644
--- a/main.c
+++ b/main.c
@@ -278,6 +278,9 @@ main(int argc, char *argv[])
/* Set this before parsing arguments */
Flag(FPRIVILEGED) = getuid() != ksheuid || getgid() != getegid();
+ /* set before parse_args */
+ writefd = 0;
+
/* this to note if monitor is set on command line (see below) */
Flag(FMONITOR) = 127;
argi = parse_args(argv, OF_CMDLINE, (int *) 0);
@@ -286,6 +289,10 @@ main(int argc, char *argv[])
/* NOTREACHED */
}
+ /* print initial cwd */
+ if (writefd)
+ dprintf(writefd, "cwd%s\n", current_wd);
+
if (Flag(FCOMMAND)) {
s = pushs(SSTRING, ATEMP);
if (!(s->start = s->str = argv[argi++]))
@@ -578,7 +585,12 @@ shell(s, toplevel)
set_prompt(PS1, s);
}
+ if (interactive && writefd)
+ dprintf(writefd, "\n");
t = compile(s);
+ if (interactive && writefd && s->start[0] != '\n')
+ dprintf(writefd, "cmd%s", s->start);
+
if (t != NULL && t->type == TEOF) {
if (wastty && Flag(FIGNOREEOF) && --attempts > 0) {
shellf("Use `exit' to leave ksh\n");
diff --git a/misc.c b/misc.c
index 393da1c..80ce13b 100644
--- a/misc.c
+++ b/misc.c
@@ -347,7 +347,7 @@ parse_args(argv, what, setargsp)
int what; /* OF_CMDLINE or OF_SET */
int *setargsp;
{
- static char cmd_opts[NELEM(goptions) + 3]; /* o:\0 */
+ static char cmd_opts[NELEM(goptions) + 5]; /* o:w:\0 */
static char set_opts[NELEM(goptions) + 5]; /* Ao;s\0 */
char *opts;
char *array = (char *) 0;
@@ -359,7 +359,7 @@ parse_args(argv, what, setargsp)
char *p, *q;
/* see cmd_opts[] declaration */
- strlcpy(cmd_opts, "o:", sizeof cmd_opts);
+ strlcpy(cmd_opts, "o:w:", sizeof cmd_opts);
p = cmd_opts + strlen(cmd_opts);
/* see set_opts[] declaration */
strlcpy(set_opts, "A:o;s", sizeof set_opts);
@@ -423,6 +423,14 @@ parse_args(argv, what, setargsp)
}
break;
+ case 'w':
+ writefd = open(go.optarg, O_WRONLY);
+ if (writefd == -1) {
+ bi_errorf("could not open %s", go.optarg);
+ return -1;
+ }
+ break;
+
case '?':
return -1;
diff --git a/path.c b/path.c
index bb18075..70d8a71 100644
--- a/path.c
+++ b/path.c
@@ -198,6 +198,8 @@ set_current_wd(pathx)
if (len > current_wd_size)
current_wd = aresize(current_wd, current_wd_size = len, APERM);
memcpy(current_wd, p, len);
+ if (writefd)
+ dprintf(writefd, "cwd%s\n", p);
if (p != pathx && p != null)
afree(p, ATEMP);
}
diff --git a/sh.h b/sh.h
index 222b77c..6cd656d 100644
--- a/sh.h
+++ b/sh.h
@@ -186,6 +186,7 @@ EXTERN uid_t ksheuid; /* effective uid of shell */
EXTERN int exstat; /* exit status */
EXTERN int subst_exstat; /* exit status of last $(..)/`..` */
EXTERN const char *safe_prompt; /* safe prompt if PS1 substitution fails */
+EXTERN int writefd; /* open file descriptor to -w file */
/*
* Area-based allocation built on malloc/free