Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/src/ui/pipecmd.c
blob: f0f4c66b887ee7e9401dac82b332fb3f08e867f0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include <config.h>
#ifndef _plan9
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#ifndef _MAC
#include <sys/types.h>
#endif
#include <fconfig.h>
#include <filter.h>
#include <fractal.h>
#include <string.h>
#include <ui_helper.h>
#include <ui.h>
#include <timers.h>
#include <xmenu.h>
#include "uiint.h"
#ifdef COMPILE_PIPE
static int pipefd = -1;
tl_timer *pipetimer;
static char pipecommand[256];
static int commandpos;
static int textmode = 0;
static int backslash = 0;
static int nest = -1;
#define add(cmd) (pipecommand[commandpos++]=cmd)
static void ui_pipe_handler(void *data, int q)
{
#ifdef O_NONBLOCK
    char buf[100];
    int n = (int) read(pipefd, buf, 100);
    int i;
    if (n > 0) {
	buf[n] = 0;
    }
    for (i = 0; i < n; i++) {
	if (backslash) {
	    add(buf[i]);
	    continue;
	}
	if (textmode) {
	    if (buf[i] == '\\') {
		add(buf[i]);
		backslash = 1;
		continue;
	    }
	    if (buf[i] == '"') {
		add(buf[i]);
		textmode = 0;
		continue;
	    }
	    add(buf[i]);
	} else {
	    add(buf[i]);
	    if (buf[i] == '"')
		textmode = 1;
	    if (buf[i] == ')')
		nest--;
	    if (buf[i] == '(') {
		if (nest == -1)
		    nest = 1;
		else
		    nest++;
	    }
	    if (!nest) {
		add(0);
		uih_command(uih, pipecommand);
		nest = -1;
		commandpos = 0;
	    }
	}
    }
#endif
}

void ui_pipe_init(CONST char *name)
{
#ifdef O_NONBLOCK
    if ((int) strlen(name) == 1 && name[0] == '-') {
	pipefd = 0;
	fcntl(pipefd, F_SETFL, O_NONBLOCK);
    } else {
	pipefd = open(name, O_NONBLOCK);
	if (pipefd == -1) {
	    perror(name);
	    exit(1);
	}
    }
    pipetimer = tl_create_timer();
    tl_set_multihandler(pipetimer, ui_pipe_handler, NULL);
    tl_reset_timer(pipetimer);
    tl_set_interval(pipetimer, 100000);
    tl_add_timer(syncgroup, pipetimer);
#else
    printf
	("Fatal error - constant O_NONBLOCK used for non-blocking IO in the pipe handling"
	 "is unknown at the moment of compilation. The non-blocking IO will not work. "
	 "Please ask authors...\n");
    exit(0);
#endif
}

static void ui_pipe_close(void)
{
#ifdef O_NONBLOCK
    if (pipefd == -1)
	return;
    close(pipefd);
    tl_remove_timer(pipetimer);
#endif
}
#endif
#endif