⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gs.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
/* * gs interface for page. * ps.c and pdf.c both use these routines. * a caveat: if you run more than one gs, only the last  * one gets killed by killgs  */#include <u.h>#include <libc.h>#include <draw.h>#include <event.h>#include <bio.h>#include "page.h"static int gspid;	/* globals for atexit */static int gsfd;static void	killgs(void);static voidkillgs(void){	char tmpfile[100];	close(gsfd);	postnote(PNGROUP, getpid(), "die");	/*	 * from ghostscript's use.txt:	 * ``Ghostscript currently doesn't do a very good job of deleting temporary	 * files when it exits; you may have to delete them manually from time to	 * time.''	 */	sprint(tmpfile, "/tmp/gs_%.5da", (gspid+300000)%100000);	if(chatty) fprint(2, "remove %s...\n", tmpfile);	remove(tmpfile);	sleep(100);	postnote(PNPROC, gspid, "die yankee pig dog");}intspawnwriter(GSInfo *g, Biobuf *b){	char buf[4096];	int n;	int fd;	switch(fork()){	case -1:	return -1;	case 0:	break;	default:	return 0;	}	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;}intspawnreader(int fd){	int n, pfd[2];	char buf[1024];	if(pipe(pfd)<0)		return -1;	switch(fork()){	case -1:		return -1;	case 0:		break;	default:		close(pfd[0]);		return pfd[1];	}	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;}voidspawnmonitor(int fd){	char buf[4096];	char *xbuf;	int n;	int out;	int first;	switch(rfork(RFFDG|RFNOTEG|RFPROC)){	case -1:	default:		return;	case 0:		break;	}	out = open("/dev/cons", OWRITE);	if(out < 0)		out = 2;	xbuf = buf;	/* for ease of acid */	first = 1;	while((n = read(fd, xbuf, sizeof buf)) > 0){		if(first){			first = 0;			fprint(2, "Ghostscript Error:\n");		}		write(out, xbuf, n);		alarm(500);	}	_exits(0);}int spawngs(GSInfo *g, char *safer){	char *args[16];	char tb[32], gb[32];	int i, nargs;	int devnull;	int stdinout[2];	int dataout[2];	int errout[2];	/*	 * spawn gs	 * 	 * gs's standard input is fed from stdinout.	 * gs output written to fd-2 (i.e. output we generate intentionally) is fed to stdinout.	 * 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)		return -1;	nargs = 0;	args[nargs++] = "gs";	args[nargs++] = "-dNOPAUSE";	args[nargs++] = safer;	args[nargs++] = "-sDEVICE=plan9";	args[nargs++] = "-sOutputFile=/fd/3";	args[nargs++] = "-dQUIET";	args[nargs++] = "-r100";	sprint(tb, "-dTextAlphaBits=%d", textbits);	sprint(gb, "-dGraphicsAlphaBits=%d", gfxbits);	if(textbits)		args[nargs++] = tb;	if(gfxbits)		args[nargs++] = gb;	args[nargs++] = "-";	args[nargs] = nil;	gspid = fork();	if(gspid == 0) {		close(stdinout[1]);		close(dataout[1]);		close(errout[1]);		/*		 * Horrible problem: we want to dup fd's 0-4 below,		 * but some of the source fd's might have those small numbers.		 * So we need to reallocate those.  In order to not step on		 * anything else, we'll dup the fd's to higher ones using		 * dup(x, -1), but we need to use up the lower ones first.		 */		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);		dup(stdinout[0], 0);		dup(errout[0], 1);		dup(devnull, 2);	/* never anything useful */		dup(dataout[0], 3);		dup(stdinout[0], 4);		for(i=5; i<20; i++)			close(i);		exec("/bin/gs", args);		wexits("exec");	}	close(stdinout[0]);	close(errout[0]);	close(dataout[0]);	atexit(killgs);	if(teegs)		stdinout[1] = spawnreader(stdinout[1]);	gsfd = g->gsfd = stdinout[1];	g->gsdfd = dataout[1];	g->gspid = gspid;	spawnmonitor(errout[1]);	Binit(&g->gsrd, g->gsfd, OREAD);	gscmd(g, "/PAGEOUT (/fd/4) (w) file def\n");	gscmd(g, "/PAGE== { PAGEOUT exch write==only PAGEOUT (\\n) writestring PAGEOUT flushfile } def\n");	waitgs(g);	return 0;}intgscmd(GSInfo *gs, char *fmt, ...){	char buf[1024];	int n;	va_list v;	va_start(v, fmt);	n = vseprint(buf, buf+sizeof buf, fmt, v) - buf;	if(n <= 0)		return n;	if(chatty) {		fprint(2, "cmd: ");		write(2, buf, n);	}	if(write(gs->gsfd, buf, n) != 0)		return -1;	return n;}/* * set the dimensions of the bitmap we expect to get back from GS. */voidsetdim(GSInfo *gs, Rectangle bbox, int ppi, int landscape){	Rectangle pbox;	if(chatty)		fprint(2, "setdim: bbox=%R\n", bbox);	if(ppi)		gs->ppi = ppi;	gscmd(gs, "mark\n");	if(ppi)		gscmd(gs, "/HWResolution [%d %d]\n", ppi, ppi);	if(!Dx(bbox))		bbox = Rect(0, 0, 612, 792);	/* 8½×11 */	switch(landscape){	case 0:		pbox = bbox;		break;	case 1:		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");	gscmd(gs, "/#copies 1 store\n");	if(!eqpt(bbox.min, ZP))		gscmd(gs, "%d %d translate\n", -bbox.min.x, -bbox.min.y);	switch(landscape){	case 0:		break;	case 1:		gscmd(gs, "%d 0 translate\n", Dy(bbox));		gscmd(gs, "90 rotate\n");		break;	}	waitgs(gs);}voidwaitgs(GSInfo *gs){	/* we figure out that gs is done by telling it to	 * print something and waiting until it does.	 */	char *p;	Biobuf *b = &gs->gsrd;	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");	alarm(300*1000);	for(;;) {		p = Brdline(b, '\n');		if(p == nil) {			n = Bbuffered(b);			if(n <= 0)				break;			if(n > sizeof buf)				n = sizeof buf;			Bread(b, buf, n);			continue;		}		p[Blinelen(b)-1] = 0;		if(chatty) fprint(2, "p: ");		if(chatty) write(2, p, Blinelen(b)-1);		if(chatty) fprint(2, "\n");		if(strstr(p, "Error:")) {			alarm(0);			fprint(2, "ghostscript error: %s\n", p);			wexits("gs error");		}		if(strstr(p, "//GO.SYSIN DD")) {			break;		}	}	alarm(0);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -