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:
parent
24b81b5969
commit
41ae60bb55
23
eval.c
23
eval.c
@ -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
18
main.c
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user