xref: /plan9/sys/src/cmd/gs/src/gp_unix.c (revision 7dd7cddf99dd7472612f1413b4da293630e6b1bc)
1*7dd7cddfSDavid du Colombier /* Copyright (C) 1989, 2000 Aladdin Enterprises.  All rights reserved.
2*7dd7cddfSDavid du Colombier 
3*7dd7cddfSDavid du Colombier    This file is part of Aladdin Ghostscript.
4*7dd7cddfSDavid du Colombier 
5*7dd7cddfSDavid du Colombier    Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author
6*7dd7cddfSDavid du Colombier    or distributor accepts any responsibility for the consequences of using it,
7*7dd7cddfSDavid du Colombier    or for whether it serves any particular purpose or works at all, unless he
8*7dd7cddfSDavid du Colombier    or she says so in writing.  Refer to the Aladdin Ghostscript Free Public
9*7dd7cddfSDavid du Colombier    License (the "License") for full details.
10*7dd7cddfSDavid du Colombier 
11*7dd7cddfSDavid du Colombier    Every copy of Aladdin Ghostscript must include a copy of the License,
12*7dd7cddfSDavid du Colombier    normally in a plain ASCII text file named PUBLIC.  The License grants you
13*7dd7cddfSDavid du Colombier    the right to copy, modify and redistribute Aladdin Ghostscript, but only
14*7dd7cddfSDavid du Colombier    under certain conditions described in the License.  Among other things, the
15*7dd7cddfSDavid du Colombier    License requires that the copyright notice and this notice be preserved on
16*7dd7cddfSDavid du Colombier    all copies.
17*7dd7cddfSDavid du Colombier  */
18*7dd7cddfSDavid du Colombier 
19*7dd7cddfSDavid du Colombier /*$Id: gp_unix.c,v 1.2 2000/03/18 01:45:16 lpd Exp $ */
20*7dd7cddfSDavid du Colombier /* Unix-specific routines for Ghostscript */
21*7dd7cddfSDavid du Colombier #include "pipe_.h"
22*7dd7cddfSDavid du Colombier #include "string_.h"
23*7dd7cddfSDavid du Colombier #include "time_.h"
24*7dd7cddfSDavid du Colombier #include "gx.h"
25*7dd7cddfSDavid du Colombier #include "gsexit.h"
26*7dd7cddfSDavid du Colombier #include "gp.h"
27*7dd7cddfSDavid du Colombier 
28*7dd7cddfSDavid du Colombier /*
29*7dd7cddfSDavid du Colombier  * This is the only place in Ghostscript that calls 'exit'.  Including
30*7dd7cddfSDavid du Colombier  * <stdlib.h> is overkill, but that's where it's declared on ANSI systems.
31*7dd7cddfSDavid du Colombier  * We don't have any way of detecting whether we have a standard library
32*7dd7cddfSDavid du Colombier  * (some GNU compilers perversely define __STDC__ but don't provide
33*7dd7cddfSDavid du Colombier  * an ANSI-compliant library), so we check __PROTOTYPES__ and
34*7dd7cddfSDavid du Colombier  * hope for the best.  We pick up getenv at the same time.
35*7dd7cddfSDavid du Colombier  */
36*7dd7cddfSDavid du Colombier #ifdef __PROTOTYPES__
37*7dd7cddfSDavid du Colombier #  include <stdlib.h>		/* for exit and getenv */
38*7dd7cddfSDavid du Colombier #else
39*7dd7cddfSDavid du Colombier extern void exit(P1(int));
40*7dd7cddfSDavid du Colombier extern char *getenv(P1(const char *));
41*7dd7cddfSDavid du Colombier 
42*7dd7cddfSDavid du Colombier #endif
43*7dd7cddfSDavid du Colombier 
44*7dd7cddfSDavid du Colombier /* Do platform-dependent initialization. */
45*7dd7cddfSDavid du Colombier void
46*7dd7cddfSDavid du Colombier gp_init(void)
47*7dd7cddfSDavid du Colombier {
48*7dd7cddfSDavid du Colombier }
49*7dd7cddfSDavid du Colombier 
50*7dd7cddfSDavid du Colombier /* Do platform-dependent cleanup. */
51*7dd7cddfSDavid du Colombier void
52*7dd7cddfSDavid du Colombier gp_exit(int exit_status, int code)
53*7dd7cddfSDavid du Colombier {
54*7dd7cddfSDavid du Colombier }
55*7dd7cddfSDavid du Colombier 
56*7dd7cddfSDavid du Colombier /* Exit the program. */
57*7dd7cddfSDavid du Colombier void
58*7dd7cddfSDavid du Colombier gp_do_exit(int exit_status)
59*7dd7cddfSDavid du Colombier {
60*7dd7cddfSDavid du Colombier     exit(exit_status);
61*7dd7cddfSDavid du Colombier }
62*7dd7cddfSDavid du Colombier 
63*7dd7cddfSDavid du Colombier /* ------ Miscellaneous ------ */
64*7dd7cddfSDavid du Colombier 
65*7dd7cddfSDavid du Colombier /* Get the string corresponding to an OS error number. */
66*7dd7cddfSDavid du Colombier /* Unix systems support this so inconsistently that we don't attempt */
67*7dd7cddfSDavid du Colombier /* to figure out whether it's available. */
68*7dd7cddfSDavid du Colombier const char *
69*7dd7cddfSDavid du Colombier gp_strerror(int errnum)
70*7dd7cddfSDavid du Colombier {
71*7dd7cddfSDavid du Colombier     return NULL;
72*7dd7cddfSDavid du Colombier }
73*7dd7cddfSDavid du Colombier 
74*7dd7cddfSDavid du Colombier /* ------ Date and time ------ */
75*7dd7cddfSDavid du Colombier 
76*7dd7cddfSDavid du Colombier /* Read the current time (in seconds since Jan. 1, 1970) */
77*7dd7cddfSDavid du Colombier /* and fraction (in nanoseconds). */
78*7dd7cddfSDavid du Colombier void
79*7dd7cddfSDavid du Colombier gp_get_realtime(long *pdt)
80*7dd7cddfSDavid du Colombier {
81*7dd7cddfSDavid du Colombier     struct timeval tp;
82*7dd7cddfSDavid du Colombier 
83*7dd7cddfSDavid du Colombier #if gettimeofday_no_timezone	/* older versions of SVR4 */
84*7dd7cddfSDavid du Colombier     {
85*7dd7cddfSDavid du Colombier 	if (gettimeofday(&tp) == -1) {
86*7dd7cddfSDavid du Colombier 	    lprintf("Ghostscript: gettimeofday failed!\n");
87*7dd7cddfSDavid du Colombier 	    gs_exit(1);
88*7dd7cddfSDavid du Colombier 	}
89*7dd7cddfSDavid du Colombier     }
90*7dd7cddfSDavid du Colombier #else /* All other systems */
91*7dd7cddfSDavid du Colombier     {
92*7dd7cddfSDavid du Colombier 	struct timezone tzp;
93*7dd7cddfSDavid du Colombier 
94*7dd7cddfSDavid du Colombier 	if (gettimeofday(&tp, &tzp) == -1) {
95*7dd7cddfSDavid du Colombier 	    lprintf("Ghostscript: gettimeofday failed!\n");
96*7dd7cddfSDavid du Colombier 	    gs_exit(1);
97*7dd7cddfSDavid du Colombier 	}
98*7dd7cddfSDavid du Colombier     }
99*7dd7cddfSDavid du Colombier #endif
100*7dd7cddfSDavid du Colombier 
101*7dd7cddfSDavid du Colombier     /* tp.tv_sec is #secs since Jan 1, 1970 */
102*7dd7cddfSDavid du Colombier     pdt[0] = tp.tv_sec;
103*7dd7cddfSDavid du Colombier 
104*7dd7cddfSDavid du Colombier     /* Some Unix systems (e.g., Interactive 3.2 r3.0) return garbage */
105*7dd7cddfSDavid du Colombier     /* in tp.tv_usec.  Try to filter out the worst of it here. */
106*7dd7cddfSDavid du Colombier     pdt[1] = tp.tv_usec >= 0 && tp.tv_usec < 1000000 ? tp.tv_usec * 1000 : 0;
107*7dd7cddfSDavid du Colombier 
108*7dd7cddfSDavid du Colombier #ifdef DEBUG_CLOCK
109*7dd7cddfSDavid du Colombier     printf("tp.tv_sec = %d  tp.tv_usec = %d  pdt[0] = %ld  pdt[1] = %ld\n",
110*7dd7cddfSDavid du Colombier 	   tp.tv_sec, tp.tv_usec, pdt[0], pdt[1]);
111*7dd7cddfSDavid du Colombier #endif
112*7dd7cddfSDavid du Colombier }
113*7dd7cddfSDavid du Colombier 
114*7dd7cddfSDavid du Colombier /* Read the current user CPU time (in seconds) */
115*7dd7cddfSDavid du Colombier /* and fraction (in nanoseconds).  */
116*7dd7cddfSDavid du Colombier void
117*7dd7cddfSDavid du Colombier gp_get_usertime(long *pdt)
118*7dd7cddfSDavid du Colombier {
119*7dd7cddfSDavid du Colombier #if use_times_for_usertime
120*7dd7cddfSDavid du Colombier     struct tms tms;
121*7dd7cddfSDavid du Colombier     long ticks;
122*7dd7cddfSDavid du Colombier     const long ticks_per_sec = CLK_TCK;
123*7dd7cddfSDavid du Colombier 
124*7dd7cddfSDavid du Colombier     times(&tms);
125*7dd7cddfSDavid du Colombier     ticks = tms.tms_utime + tms.tms_stime + tms.tms_cutime + tms.tms_cstime;
126*7dd7cddfSDavid du Colombier     pdt[0] = ticks / ticks_per_sec;
127*7dd7cddfSDavid du Colombier     pdt[1] = (ticks % ticks_per_sec) * (1000000000 / ticks_per_sec);
128*7dd7cddfSDavid du Colombier #else
129*7dd7cddfSDavid du Colombier     gp_get_realtime(pdt);	/* Use an approximation on other hosts.  */
130*7dd7cddfSDavid du Colombier #endif
131*7dd7cddfSDavid du Colombier }
132*7dd7cddfSDavid du Colombier 
133*7dd7cddfSDavid du Colombier /* ------ Screen management ------ */
134*7dd7cddfSDavid du Colombier 
135*7dd7cddfSDavid du Colombier /* Get the environment variable that specifies the display to use. */
136*7dd7cddfSDavid du Colombier const char *
137*7dd7cddfSDavid du Colombier gp_getenv_display(void)
138*7dd7cddfSDavid du Colombier {
139*7dd7cddfSDavid du Colombier     return getenv("DISPLAY");
140*7dd7cddfSDavid du Colombier }
141*7dd7cddfSDavid du Colombier 
142*7dd7cddfSDavid du Colombier /* ------ Printer accessing ------ */
143*7dd7cddfSDavid du Colombier 
144*7dd7cddfSDavid du Colombier /* Open a connection to a printer.  See gp.h for details. */
145*7dd7cddfSDavid du Colombier FILE *
146*7dd7cddfSDavid du Colombier gp_open_printer(char fname[gp_file_name_sizeof], int binary_mode)
147*7dd7cddfSDavid du Colombier {
148*7dd7cddfSDavid du Colombier     const char *fmode = (binary_mode ? "wb" : "w");
149*7dd7cddfSDavid du Colombier 
150*7dd7cddfSDavid du Colombier     return (strlen(fname) == 0 ? 0 : fopen(fname, fmode));
151*7dd7cddfSDavid du Colombier }
152*7dd7cddfSDavid du Colombier 
153*7dd7cddfSDavid du Colombier /* Close the connection to the printer. */
154*7dd7cddfSDavid du Colombier void
155*7dd7cddfSDavid du Colombier gp_close_printer(FILE * pfile, const char *fname)
156*7dd7cddfSDavid du Colombier {
157*7dd7cddfSDavid du Colombier     if (fname[0] == '|')
158*7dd7cddfSDavid du Colombier 	pclose(pfile);
159*7dd7cddfSDavid du Colombier     else
160*7dd7cddfSDavid du Colombier 	fclose(pfile);
161*7dd7cddfSDavid du Colombier }
162