[hackers] [9base] apply changes from https://github.com/9fans/plan9port on rc/havefork.c || pranomostro

From: <git_AT_suckless.org>
Date: Fri, 30 Jun 2017 10:55:31 +0200 (CEST)

commit 1583c9239d968bbc571190d2cf563146a9704528
Author: pranomostro <pranomestro_AT_gmail.com>
AuthorDate: Sat May 20 01:06:03 2017 +0200
Commit: Anselm R Garbe <anselm_AT_ip-172-26-9-55.eu-central-1.compute.internal>
CommitDate: Fri Jun 30 08:54:10 2017 +0000

    apply changes from https://github.com/9fans/plan9port on rc/havefork.c
    
    before applying those changes, rc exited with sigsegv when receiving
    sigint while executing a command in a subshell (example: rc -c '`{read}').

diff --git a/rc/havefork.c b/rc/havefork.c
index 1cd8ed2..909ef33 100644
--- a/rc/havefork.c
+++ b/rc/havefork.c
_AT_@ -1,3 +1,5 @@
+#include <u.h>
+#include <signal.h>
 #include "rc.h"
 #include "getflags.h"
 #include "exec.h"
_AT_@ -71,31 +73,23 @@ Xpipe(void)
         }
 }
 
-char*
-erealloc(char *p, long n)
-{
- p = realloc(p, n); /* botch, should be Realloc */
- if(p==0)
- panic("Can't realloc %d bytes\n", n);
- return p;
-}
-
 /*
  * Who should wait for the exit from the fork?
  */
-enum { Stralloc = 100, };
-
 void
 Xbackq(void)
 {
- int c, l, pid;
- int pfd[2];
- char *s, *wd, *ewd, *stop;
+ struct thread *p = runq;
+ char wd[8193];
+ int c, n;
+ char *s, *ewd=&wd[8192], *stop, *q;
         struct io *f;
         var *ifs = vlook("ifs");
         word *v, *nextv;
-
- stop = ifs->val? ifs->val->word: "";
+ int pfd[2];
+ int pid;
+ Rune r;
+ stop = ifs->val?ifs->val->word:"";
         if(pipe(pfd)<0){
                 Xerror("can't make pipe");
                 return;
_AT_@ -116,30 +110,31 @@ Xbackq(void)
                 addwaitpid(pid);
                 close(pfd[PWR]);
                 f = openfd(pfd[PRD]);
- s = wd = ewd = 0;
+ s = wd;
                 v = 0;
                 while((c = rchr(f))!=EOF){
- if(s==ewd){
- l = s-wd;
- wd = erealloc(wd, l+Stralloc);
- ewd = wd+l+Stralloc-1;
- s = wd+l;
- }
- if(strchr(stop, c)){
- if(s!=wd){
- *s='\0';
- v = newword(wd, v);
- s = wd;
+ if(s != ewd) {
+ *s++ = c;
+ for(q=stop; *q; q+=n) {
+ n = chartorune(&r, q);
+ if(s-wd >= n && memcmp(s-n, q, n) == 0) {
+ s -= n;
+ goto stop;
+ }
                                 }
+ continue;
+ }
+ stop:
+ if(s != wd) {
+ *s = '\0';
+ v = newword(wd, v);
                         }
- else *s++=c;
+ s = wd;
                 }
                 if(s!=wd){
                         *s='\0';
                         v = newword(wd, v);
                 }
- if(wd)
- efree(wd);
                 closeio(f);
                 Waitfor(pid, 0);
                 /* v points to reversed arglist -- reverse it onto argv */
_AT_@ -149,7 +144,7 @@ Xbackq(void)
                         runq->argv->words = v;
                         v = nextv;
                 }
- runq->pc = runq->code[runq->pc].i;
+ p->pc = p->code[p->pc].i;
                 return;
         }
 }
_AT_@ -161,18 +156,33 @@ Xpipefd(void)
         int pc = p->pc, pid;
         char name[40];
         int pfd[2];
- int sidefd, mainfd;
- if(pipe(pfd)<0){
- Xerror("can't get pipe");
- return;
+ struct { int sidefd, mainfd; } fd[2], *r, *w;
+
+ r = &fd[0];
+ w = &fd[1];
+ switch(p->code[pc].i){
+ case READ:
+ w = nil;
+ break;
+ case WRITE:
+ r = nil;
         }
- if(p->code[pc].i==READ){
- sidefd = pfd[PWR];
- mainfd = pfd[PRD];
+
+ if(r){
+ if(pipe(pfd)<0){
+ Xerror("can't get pipe");
+ return;
+ }
+ r->sidefd = pfd[PWR];
+ r->mainfd = pfd[PRD];
         }
- else{
- sidefd = pfd[PRD];
- mainfd = pfd[PWR];
+ if(w){
+ if(pipe(pfd)<0){
+ Xerror("can't get pipe");
+ return;
+ }
+ w->sidefd = pfd[PRD];
+ w->mainfd = pfd[PWR];
         }
         switch(pid = fork()){
         case -1:
_AT_@ -181,17 +191,32 @@ Xpipefd(void)
         case 0:
                 clearwaitpids();
                 start(p->code, pc+2, runq->local);
- close(mainfd);
- pushredir(ROPEN, sidefd, p->code[pc].i==READ?1:0);
+ if(r){
+ close(r->mainfd);
+ pushredir(ROPEN, r->sidefd, 1);
+ }
+ if(w){
+ close(w->mainfd);
+ pushredir(ROPEN, w->sidefd, 0);
+ }
                 runq->ret = 0;
                 break;
         default:
                 addwaitpid(pid);
- close(sidefd);
- pushredir(ROPEN, mainfd, mainfd); /* isn't this a noop? */
- strcpy(name, Fdprefix);
- inttoascii(name+strlen(name), mainfd);
- pushword(name);
+ if(w){
+ close(w->sidefd);
+ pushredir(ROPEN, w->mainfd, w->mainfd); /* so that Xpopredir can close it later */
+ strcpy(name, Fdprefix);
+ inttoascii(name+strlen(name), w->mainfd);
+ pushword(name);
+ }
+ if(r){
+ close(r->sidefd);
+ pushredir(ROPEN, r->mainfd, r->mainfd);
+ strcpy(name, Fdprefix);
+ inttoascii(name+strlen(name), r->mainfd);
+ pushword(name);
+ }
                 p->pc = p->code[pc+1].i;
                 break;
         }
Received on Fri Jun 30 2017 - 10:55:31 CEST

This archive was generated by hypermail 2.3.0 : Fri Jun 30 2017 - 11:00:20 CEST