now that funsub() is a separate function, and we don’t have the clobber

issue from longjmp any more, and that I thought to rewind the fd, finally
implement ${ …;} on deleted-after-open tempfiles without the need to reopen
This commit is contained in:
tg 2013-03-29 17:33:07 +00:00
parent 24b81b5969
commit 41ae60bb55
2 changed files with 23 additions and 18 deletions

23
eval.c
View File

@ -23,7 +23,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.137 2013/02/23 20:03:30 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/eval.c,v 1.138 2013/03/29 17:33:06 tg Exp $");
/* /*
* string expansion * string expansion
@ -1341,28 +1341,31 @@ comsub(Expand *xp, const char *cp, int fn MKSH_A_UNUSED)
int ofd1; int ofd1;
struct temp *tf = NULL; struct temp *tf = NULL;
/* create a temporary file, open for writing */ /*
* create a temporary file, open for reading and writing,
* with an shf open for reading (buffered) but yet unused
*/
maketemp(ATEMP, TT_FUNSUB, &tf); maketemp(ATEMP, TT_FUNSUB, &tf);
if (!tf->shf) { if (!tf->shf) {
errorf("can't %s temporary file %s: %s", errorf("can't %s temporary file %s: %s",
"create", tf->tffn, cstrerror(errno)); "create", tf->tffn, cstrerror(errno));
} }
/* save stdout and make the temporary file it */ /* extract shf from temporary file, unlink and free it */
shf = tf->shf;
unlink(tf->tffn);
afree(tf, ATEMP);
/* save stdout and let it point to the tempfile */
ofd1 = savefd(1); ofd1 = savefd(1);
ksh_dup2(shf_fileno(tf->shf), 1, false); ksh_dup2(shf_fileno(shf), 1, false);
/* /*
* run tree, with output thrown into the tempfile, * run tree, with output thrown into the tempfile,
* in a new function block * in a new function block
*/ */
funsub(t); funsub(t);
subst_exstat = exstat & 0xFF; subst_exstat = exstat & 0xFF;
/* close the tempfile and restore regular stdout */ /* rewind the tempfile and restore regular stdout */
shf_close(tf->shf); lseek(shf_fileno(shf), (off_t)0, SEEK_SET);
restfd(1, ofd1); restfd(1, ofd1);
/* now open, unlink and free the tempfile for reading */
shf = shf_open(tf->tffn, O_RDONLY, 0, SHF_MAPHI | SHF_CLEXEC);
unlink(tf->tffn);
afree(tf, ATEMP);
} else { } else {
int ofd1, pv[2]; int ofd1, pv[2];

18
main.c
View File

@ -34,7 +34,7 @@
#include <locale.h> #include <locale.h>
#endif #endif
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.260 2013/02/10 21:42:16 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/main.c,v 1.261 2013/03/29 17:33:07 tg Exp $");
extern char **environ; extern char **environ;
@ -1594,7 +1594,7 @@ maketemp(Area *ap, Temp_type type, struct temp **tlist)
{ {
char *cp; char *cp;
size_t len; size_t len;
int i; int i, j;
struct temp *tp; struct temp *tp;
const char *dir; const char *dir;
struct stat sb; struct stat sb;
@ -1644,17 +1644,19 @@ maketemp(Area *ap, Temp_type type, struct temp **tlist)
} }
if (type == TT_FUNSUB) { if (type == TT_FUNSUB) {
int nfd;
/* map us high and mark as close-on-exec */ /* map us high and mark as close-on-exec */
if ((nfd = savefd(i)) != i) { if ((j = savefd(i)) != i) {
close(i); close(i);
i = nfd; i = j;
} }
}
/* operation mode for the shf */
j = SHF_RD;
} else
j = SHF_WR;
/* shf_fdopen cannot fail, so no fd leak */ /* shf_fdopen cannot fail, so no fd leak */
tp->shf = shf_fdopen(i, SHF_WR, NULL); tp->shf = shf_fdopen(i, j, NULL);
maketemp_out: maketemp_out:
tp->next = *tlist; tp->next = *tlist;