Skip to content

Commit

Permalink
Do not fork & fix interrupts
Browse files Browse the repository at this point in the history
Though POSIX defines a minimum for pipe buffer, I decided is safer writing one byte a time. This may render slow reads, though writing in larger quantities rendered broken reads.

For an unknown reason, some operations, after SIGINT, rendered exiting the Shell. This happens on the ERR_RECURSION error as well. longjmp remedies the issue, though I'm afraid isn't the best solution.
  • Loading branch information
Krush206 committed Jun 3, 2024
1 parent 954cfd6 commit 15d4e30
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 15 deletions.
4 changes: 3 additions & 1 deletion sh.err.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,8 @@ extern int enterhist;
#define ERR_RETURN 138
#define ERR_FUNCBEGIN 139
#define ERR_FUNCALNUM 140
#define NO_ERRORS 141
#define ERR_RECURSION 141
#define NO_ERRORS 142

static const char *elst[NO_ERRORS] INIT_ZERO_STRUCT;

Expand Down Expand Up @@ -375,6 +376,7 @@ errinit(void)
elst[ERR_RETURN] = CSAVS(1, 141, "Not in a declaration");
elst[ERR_FUNCBEGIN] = CSAVS(1, 142, "Function name must begin with a letter");
elst[ERR_FUNCALNUM] = CSAVS(1, 143, "Function name must contain alphanumeric characters");
elst[ERR_RECURSION] = CSAVS(1, 144, "Recursion too deep");
}

/* Cleanup data. */
Expand Down
42 changes: 28 additions & 14 deletions sh.func.c
Original file line number Diff line number Diff line change
Expand Up @@ -2725,17 +2725,21 @@ getYN(const char *prompt)
return doit;
}

int fpipe;
Char *fdecl;

void
dofunction(Char **v, struct command *c)
{
if (*++v == NULL) {
plist(&functions, VAR_ALL);
plist(&functions, VAR_READONLY);

return;
}
Sgoal = *v++;
Stype = TC_EXIT;
{
static int l;
int pv[2];
struct saved_state st;
struct varent *varp;
Expand All @@ -2747,20 +2751,31 @@ dofunction(Char **v, struct command *c)
if (!alnum(*p))
stderror(ERR_NAME | ERR_FUNCALNUM);
if ((varp = adrof1(Sgoal, &functions))) {
mypipe(pv);
if (!pfork(c, -1)) {
xclose(pv[0]);
while (**varp->vec)
xwrite(pv[1], (*varp->vec)++, 1);
xclose(pv[1]);
xexit(0);
}
pwait();
jmp_buf_t oldexit;
int pvsav, ohaderr;
Char *fsav;

xclose(pv[1]);
if (l == 16)
stderror(ERR_RECURSION);
mypipe(pv);
st_save(&st, pv[0], 0, NULL, v);
process(0);
pvsav = fpipe;
fpipe = pv[1];
fsav = fdecl;
fdecl = *varp->vec;
ohaderr = haderr;
getexit(oldexit);
if (!setexit()) {
l++;
process(0);
}
resexit(oldexit);
haderr = ohaderr;
st_restore(&st);
xclose(pv[1]);
fpipe = pvsav;
fdecl = fsav;
l--;

return;
}
Expand All @@ -2774,7 +2789,6 @@ dofunction(Char **v, struct command *c)
func = Strbuf_INIT;
struct wordent *histent = NULL,
*ohistent = NULL;
char *prompt = short2str(*c->t_dcom);

cleanup_push(&aword, Strbuf_cleanup);
while (1) {
Expand All @@ -2786,7 +2800,7 @@ dofunction(Char **v, struct command *c)
histent->prev = ohistent;
}
if (intty && fseekp == feobp && aret == TCSH_F_SEEK)
printprompt(1, prompt);
printprompt(1, bname);
(void) getword(&aword);
Strbuf_terminate(&aword);
if (intty && Strlen(aword.s) > 0) {
Expand Down
3 changes: 3 additions & 0 deletions sh.h
Original file line number Diff line number Diff line change
Expand Up @@ -1335,5 +1335,8 @@ struct saved_state {
#define TEXP_IGNORE 1 /* in ignore, it means to ignore value, just parse */
#define TEXP_NOGLOB 2 /* in ignore, it means not to globone */

extern int fpipe; /* Write end of a pipe used by dofunction. */
extern Char *fdecl; /* Pointer to function declaration
* used by dofunction. */

#endif /* _h_sh */
5 changes: 5 additions & 0 deletions sh.lex.c
Original file line number Diff line number Diff line change
Expand Up @@ -1717,6 +1717,11 @@ bgetc(void)
buf = (int) feobp / BUFSIZE;
balloc(buf);
roomleft = BUFSIZE - off;
if (fpipe) {
if (!*fdecl)
return CHAR_ERR;
(void) xwrite(fpipe, fdecl++, (size_t) 1);
}
c = wide_read(SHIN, fbuf[buf] + off, roomleft, 0);
if (c > 0)
feobp += c;
Expand Down

0 comments on commit 15d4e30

Please sign in to comment.