aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/page/gs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/page/gs.c')
-rw-r--r--src/cmd/page/gs.c175
1 files changed, 74 insertions, 101 deletions
diff --git a/src/cmd/page/gs.c b/src/cmd/page/gs.c
index fd7337ec..8c0e1b59 100644
--- a/src/cmd/page/gs.c
+++ b/src/cmd/page/gs.c
@@ -7,9 +7,9 @@
#include <u.h>
#include <libc.h>
#include <draw.h>
-#include <cursor.h>
-#include <event.h>
+#include <thread.h>
#include <bio.h>
+#include <cursor.h>
#include "page.h"
static int gspid; /* globals for atexit */
@@ -37,87 +37,41 @@ killgs(void)
postnote(PNPROC, gspid, "die yankee pig dog");
}
-int
-spawnwriter(GSInfo *g, Biobuf *b)
+void
+spawnreader(void *cp)
{
- char buf[4096];
- int n;
- int fd;
+ int n, fd, pfd[2];
+ char buf[1024];
- switch(fork()){
- case -1: return -1;
- case 0: break;
- default: return 0;
- }
+ recv(cp, &fd);
- Bseek(b, 0, 0);
- fd = g->gsfd;
- while((n = Bread(b, buf, sizeof buf)) > 0)
- write(fd, buf, n);
- fprint(fd, "(/fd/3) (w) file dup (THIS IS NOT AN INFERNO BITMAP\\n) writestring flushfile\n");
- _exits(0);
- return -1;
-}
+ if(pipe(pfd)<0)
+ wexits("pipe failed");
-int
-spawnreader(int fd)
-{
- int n, pfd[2];
- char buf[1024];
+ send(cp, &pfd[1]);
- if(pipe(pfd)<0)
- return -1;
- switch(fork()){
- case -1:
- return -1;
- case 0:
- break;
- default:
- close(pfd[0]);
- return pfd[1];
+ while((n=read(pfd[0], buf, sizeof buf)) > 0) {
+ write(1, buf, n);
+ write(fd, buf, n);
}
- close(pfd[1]);
- switch(fork()){
- case -1:
- wexits("fork failed");
- case 0:
- while((n=read(fd, buf, sizeof buf)) > 0) {
- write(1, buf, n);
- write(pfd[0], buf, n);
- }
- break;
- default:
- while((n=read(pfd[0], buf, sizeof buf)) > 0) {
- write(1, buf, n);
- write(fd, buf, n);
- }
- break;
- }
- postnote(PNGROUP, getpid(), "i'm die-ing");
- _exits(0);
- return -1;
+ close(pfd[0]);
+ threadexits(0);
}
void
-spawnmonitor(int fd)
+spawnmonitor(void *cp)
{
char buf[4096];
char *xbuf;
+ int fd;
int n;
int out;
int first;
- switch(rfork(RFFDG|RFNOTEG|RFPROC)){
- case -1:
- default:
- return;
-
- case 0:
- break;
- }
+ recv(cp, &fd);
- out = open("/dev/cons", OWRITE);
+ out = open("/dev/tty", OWRITE);
if(out < 0)
out = 2;
@@ -131,17 +85,19 @@ spawnmonitor(int fd)
write(out, xbuf, n);
alarm(500);
}
- _exits(0);
+ threadexits(0);
}
int
spawngs(GSInfo *g, char *safer)
{
+ Channel *cp;
char *args[16];
char tb[32], gb[32];
int i, nargs;
int devnull;
- int stdinout[2];
+ int stdinp[2];
+ int stdoutp[2];
int dataout[2];
int errout[2];
@@ -153,15 +109,15 @@ spawngs(GSInfo *g, char *safer)
* gs output written to fd 1 (i.e. ouptut gs generates on error) is fed to errout.
* gs data output is written to fd 3, which is dataout.
*/
- if(pipe(stdinout) < 0 || pipe(dataout)<0 || pipe(errout)<0)
+ if(pipe(stdinp)<0 || pipe(stdoutp)<0 || pipe(dataout)<0 || pipe(errout)<0)
return -1;
nargs = 0;
args[nargs++] = "gs";
args[nargs++] = "-dNOPAUSE";
- args[nargs++] = safer;
- args[nargs++] = "-sDEVICE=plan9";
- args[nargs++] = "-sOutputFile=/fd/3";
+ args[nargs++] = "-dDELAYSAFER";
+ args[nargs++] = "-sDEVICE=bmp16m";
+ args[nargs++] = "-sOutputFile=/dev/fd/3";
args[nargs++] = "-dQUIET";
args[nargs++] = "-r100";
sprint(tb, "-dTextAlphaBits=%d", textbits);
@@ -175,9 +131,10 @@ spawngs(GSInfo *g, char *safer)
gspid = fork();
if(gspid == 0) {
- close(stdinout[1]);
- close(dataout[1]);
- close(errout[1]);
+ close(stdinp[1]);
+ close(stdoutp[0]);
+ close(dataout[0]);
+ close(errout[0]);
/*
* Horrible problem: we want to dup fd's 0-4 below,
@@ -189,36 +146,49 @@ spawngs(GSInfo *g, char *safer)
while((devnull = open("/dev/null", ORDWR)) < 5)
;
- stdinout[0] = dup(stdinout[0], -1);
- errout[0] = dup(errout[0], -1);
- dataout[0] = dup(dataout[0], -1);
+ stdinp[0] = dup(stdinp[0], -1);
+ stdoutp[1] = dup(stdoutp[1], -1);
+ errout[1] = dup(errout[1], -1);
+ dataout[1] = dup(dataout[1], -1);
- dup(stdinout[0], 0);
- dup(errout[0], 1);
- dup(devnull, 2); /* never anything useful */
- dup(dataout[0], 3);
- dup(stdinout[0], 4);
+ dup(stdinp[0], 0);
+ dup(errout[1], 1);
+ dup(errout[1], devnull); /* never anything useful */
+ dup(dataout[1], 3);
+ dup(stdoutp[1], 4);
for(i=5; i<20; i++)
close(i);
- exec("/bin/gs", args);
+ execvp("gs", args);
wexits("exec");
}
- close(stdinout[0]);
- close(errout[0]);
- close(dataout[0]);
+ close(stdinp[0]);
+ close(stdoutp[1]);
+ close(errout[1]);
+ close(dataout[1]);
atexit(killgs);
- if(teegs)
- stdinout[1] = spawnreader(stdinout[1]);
+ cp = chancreate(sizeof(int), 0);
+ if(teegs) {
+ proccreate(spawnreader, cp, mainstacksize);
+ send(cp, &stdoutp[0]);
+ recv(cp, &stdoutp[0]);
+ }
- gsfd = g->gsfd = stdinout[1];
- g->gsdfd = dataout[1];
+ gsfd = g->gsfd = stdinp[1];
g->gspid = gspid;
+ g->g.fd = dataout[0];
+ g->g.name = "gs pipe";
+ g->g.type = Ibmp;
+
+ proccreate(spawnmonitor, cp, mainstacksize);
+ send(cp, &errout[0]);
+ chanfree(cp);
- spawnmonitor(errout[1]);
- Binit(&g->gsrd, g->gsfd, OREAD);
+ Binit(&g->gsrd, stdoutp[0], OREAD);
- gscmd(g, "/PAGEOUT (/fd/4) (w) file def\n");
+ gscmd(g, "/PAGEOUT (/dev/fd/4) (w) file def\n");
+ if(!strcmp(safer, "-dSAFER"))
+ gscmd(g, ".setsafe\n");
gscmd(g, "/PAGE== { PAGEOUT exch write==only PAGEOUT (\\n) writestring PAGEOUT flushfile } def\n");
waitgs(g);
@@ -269,11 +239,14 @@ setdim(GSInfo *gs, Rectangle bbox, int ppi, int landscape)
if(!Dx(bbox))
bbox = Rect(0, 0, 612, 792); /* 8½×11 */
- if(landscape)
- pbox = Rect(bbox.min.y, bbox.min.x, bbox.max.y, bbox.max.x);
- else
+ switch(landscape){
+ case 0:
pbox = bbox;
-
+ break;
+ default:
+ pbox = Rect(bbox.min.y, bbox.min.x, bbox.max.y, bbox.max.x);
+ break;
+ }
gscmd(gs, "/PageSize [%d %d]\n", Dx(pbox), Dy(pbox));
gscmd(gs, "/Margins [%d %d]\n", -pbox.min.x, -pbox.min.y);
gscmd(gs, "currentdevice putdeviceprops pop\n");
@@ -305,10 +278,10 @@ waitgs(GSInfo *gs)
uchar buf[1024];
int n;
-/* gscmd(gs, "(\\n**bstack\\n) print flush\n"); */
-/* gscmd(gs, "stack flush\n"); */
-/* gscmd(gs, "(**estack\\n) print flush\n"); */
- gscmd(gs, "(\\n/*GO.SYSIN DD\\n) PAGE==\n"); */
+// gscmd(gs, "(\\n**bstack\\n) print flush\n");
+// gscmd(gs, "stack flush\n");
+// gscmd(gs, "(**estack\\n) print flush\n");
+ gscmd(gs, "(\\n//GO.SYSIN DD\\n) PAGE==\n");
alarm(300*1000);
for(;;) {