sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | Refs

st-externalpipe-0.4.1.diff (2070B)


      1 diff --git a/st.c b/st.c
      2 index 686ed5d..697cd43 100644
      3 --- a/st.c
      4 +++ b/st.c
      5 @@ -249,6 +249,7 @@ typedef union {
      6  	unsigned int ui;
      7  	float f;
      8  	const void *v;
      9 +	const char *s;
     10  } Arg;
     11  
     12  typedef struct {
     13 @@ -263,6 +264,7 @@ static void clippaste(const Arg *);
     14  static void numlock(const Arg *);
     15  static void selpaste(const Arg *);
     16  static void xzoom(const Arg *);
     17 +static void externalpipe(const Arg *);
     18  
     19  /* Config.h for applying patches and the configuration. */
     20  #include "config.h"
     21 @@ -1024,15 +1026,22 @@ execsh(void) {
     22  void
     23  sigchld(int a) {
     24  	int stat = 0;
     25 +	pid_t r;
     26  
     27 -	if(waitpid(pid, &stat, 0) < 0)
     28 -		die("Waiting for pid %hd failed: %s\n",	pid, SERRNO);
     29 +	r = wait(&stat);
     30 +	if(r < 0)
     31 +		die("wait(): %s\n", SERRNO);
     32  
     33 -	if(WIFEXITED(stat)) {
     34 -		exit(WEXITSTATUS(stat));
     35 -	} else {
     36 -		exit(EXIT_FAILURE);
     37 +	if(r == pid){
     38 +		/* _the_ sub process */
     39 +		if(WIFEXITED(stat)) {
     40 +			exit(WEXITSTATUS(stat));
     41 +		} else {
     42 +			exit(EXIT_FAILURE);
     43 +		}
     44  	}
     45 +
     46 +	/* something else we've forked out */
     47  }
     48  
     49  void
     50 @@ -2593,6 +2602,59 @@ xzoom(const Arg *arg) {
     51  }
     52  
     53  void
     54 +externalpipe(const Arg *arg)
     55 +{
     56 +	int to[2]; /* 0 = read, 1 = write */
     57 +	pid_t child;
     58 +	int y, x;
     59 +	void (*oldsigpipe)(int);
     60 +
     61 +	if(pipe(to) == -1)
     62 +		return;
     63 +
     64 +	/* sigchld() handles this */
     65 +	switch((child = fork())){
     66 +		case -1:
     67 +			close(to[0]), close(to[1]);
     68 +			return;
     69 +		case 0:
     70 +			/* child */
     71 +			close(to[1]);
     72 +			dup2(to[0], STDIN_FILENO); /* 0<&to */
     73 +			close(to[0]);
     74 +			execvp(
     75 +					"sh",
     76 +					(char *const []){
     77 +						"/bin/sh",
     78 +						"-c",
     79 +						(char *)arg->s,
     80 +						0
     81 +					});
     82 +			exit(127);
     83 +	}
     84 +
     85 +	/* parent */
     86 +	close(to[0]);
     87 +	/* ignore sigpipe for now, in case child exits early */
     88 +	oldsigpipe = signal(SIGPIPE, SIG_IGN);
     89 +
     90 +	for(y = 0; y < term.row; y++){
     91 +		for(x = 0; x < term.col; x++){
     92 +			if(write(to[1], term.line[y][x].c, 1) == -1)
     93 +				goto done;
     94 +		}
     95 +		if(write(to[1], "\n", 1) == -1)
     96 +			break;
     97 +	}
     98 +
     99 +done:
    100 +	close(to[1]);
    101 +
    102 +	/* restore */
    103 +	signal(SIGPIPE, oldsigpipe);
    104 +}
    105 +
    106 +void
    107  xinit(void) {
    108  	XSetWindowAttributes attrs;
    109  	XGCValues gcvalues;