1 /* Copyright (C) 1989-2003 artofcode LLC. All rights reserved.
2
3 This software is provided AS-IS with no warranty, either express or
4 implied.
5
6 This software is distributed under license and may not be copied,
7 modified or distributed except as expressly authorized under the terms
8 of the license contained in the file LICENSE in this distribution.
9
10 For more information about licensing, please refer to
11 http://www.ghostscript.com/licensing/. For information on
12 commercial licensing, go to http://www.artifex.com/licensing/ or
13 contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14 San Rafael, CA 94903, U.S.A., +1(415)492-9861.
15 */
16
17 /* $Id: gp_unix.c,v 1.13 2004/01/15 09:27:10 giles Exp $ */
18 /* Unix-specific routines for Ghostscript */
19
20 #include "pipe_.h"
21 #include "string_.h"
22 #include "time_.h"
23 #include "gx.h"
24 #include "gsexit.h"
25 #include "gp.h"
26
27 /*
28 * This is the only place in Ghostscript that calls 'exit'. Including
29 * <stdlib.h> is overkill, but that's where it's declared on ANSI systems.
30 * We don't have any way of detecting whether we have a standard library
31 * (some GNU compilers perversely define __STDC__ but don't provide
32 * an ANSI-compliant library), so we check __PROTOTYPES__ and
33 * hope for the best. We pick up getenv at the same time.
34 */
35 #ifdef __PROTOTYPES__
36 # include <stdlib.h> /* for exit and getenv */
37 #else
38 extern void exit(int);
39 extern char *getenv(const char *);
40 #endif
41
42 /* Do platform-dependent initialization. */
43 void
gp_init(void)44 gp_init(void)
45 {
46 }
47
48 /* Do platform-dependent cleanup. */
49 void
gp_exit(int exit_status,int code)50 gp_exit(int exit_status, int code)
51 {
52 }
53
54 /* Exit the program. */
55 void
gp_do_exit(int exit_status)56 gp_do_exit(int exit_status)
57 {
58 exit(exit_status);
59 }
60
61 /* ------ Miscellaneous ------ */
62
63 /* Get the string corresponding to an OS error number. */
64 /* Unix systems support this so inconsistently that we don't attempt */
65 /* to figure out whether it's available. */
66 const char *
gp_strerror(int errnum)67 gp_strerror(int errnum)
68 {
69 return NULL;
70 }
71
72 /* read in a MacOS 'resource' from an extended attribute. */
73 /* we don't try to implemented this since it requires support */
74 /* for Apple's HFS(+) filesystem */
75 int
gp_read_macresource(byte * buf,const char * filename,const uint type,const ushort id)76 gp_read_macresource(byte *buf, const char *filename,
77 const uint type, const ushort id)
78 {
79 return 0;
80 }
81
82 /* ------ Date and time ------ */
83
84 /* Read the current time (in seconds since Jan. 1, 1970) */
85 /* and fraction (in nanoseconds). */
86 void
gp_get_realtime(long * pdt)87 gp_get_realtime(long *pdt)
88 {
89 struct timeval tp;
90
91 #if gettimeofday_no_timezone /* older versions of SVR4 */
92 {
93 if (gettimeofday(&tp) == -1) {
94 lprintf("Ghostscript: gettimeofday failed!\n");
95 tp.tv_sec = tp.tv_usec = 0;
96 }
97 }
98 #else /* All other systems */
99 {
100 struct timezone tzp;
101
102 if (gettimeofday(&tp, &tzp) == -1) {
103 lprintf("Ghostscript: gettimeofday failed!\n");
104 tp.tv_sec = tp.tv_usec = 0;
105 }
106 }
107 #endif
108
109 /* tp.tv_sec is #secs since Jan 1, 1970 */
110 pdt[0] = tp.tv_sec;
111
112 /* Some Unix systems (e.g., Interactive 3.2 r3.0) return garbage */
113 /* in tp.tv_usec. Try to filter out the worst of it here. */
114 pdt[1] = tp.tv_usec >= 0 && tp.tv_usec < 1000000 ? tp.tv_usec * 1000 : 0;
115
116 #ifdef DEBUG_CLOCK
117 printf("tp.tv_sec = %d tp.tv_usec = %d pdt[0] = %ld pdt[1] = %ld\n",
118 tp.tv_sec, tp.tv_usec, pdt[0], pdt[1]);
119 #endif
120 }
121
122 /* Read the current user CPU time (in seconds) */
123 /* and fraction (in nanoseconds). */
124 void
gp_get_usertime(long * pdt)125 gp_get_usertime(long *pdt)
126 {
127 #if use_times_for_usertime
128 struct tms tms;
129 long ticks;
130 const long ticks_per_sec = CLK_TCK;
131
132 times(&tms);
133 ticks = tms.tms_utime + tms.tms_stime + tms.tms_cutime + tms.tms_cstime;
134 pdt[0] = ticks / ticks_per_sec;
135 pdt[1] = (ticks % ticks_per_sec) * (1000000000 / ticks_per_sec);
136 #else
137 gp_get_realtime(pdt); /* Use an approximation on other hosts. */
138 #endif
139 }
140
141 /* ------ Screen management ------ */
142
143 /* Get the environment variable that specifies the display to use. */
144 const char *
gp_getenv_display(void)145 gp_getenv_display(void)
146 {
147 return getenv("DISPLAY");
148 }
149
150 /* ------ Printer accessing ------ */
151
152 /* Open a connection to a printer. See gp.h for details. */
153 FILE *
gp_open_printer(char fname[gp_file_name_sizeof],int binary_mode)154 gp_open_printer(char fname[gp_file_name_sizeof], int binary_mode)
155 {
156 const char *fmode = (binary_mode ? "wb" : "w");
157
158 return (strlen(fname) == 0 ? 0 : fopen(fname, fmode));
159 }
160
161 /* Close the connection to the printer. */
162 void
gp_close_printer(FILE * pfile,const char * fname)163 gp_close_printer(FILE * pfile, const char *fname)
164 {
165 if (fname[0] == '|')
166 pclose(pfile);
167 else
168 fclose(pfile);
169 }
170
171 /* ------ Font enumeration ------ */
172
173 /* This is used to query the native os for a list of font names and
174 * corresponding paths. The general idea is to save the hassle of
175 * building a custom fontmap file.
176 */
177
gp_enumerate_fonts_init(gs_memory_t * mem)178 void *gp_enumerate_fonts_init(gs_memory_t *mem)
179 {
180 return NULL;
181 }
182
gp_enumerate_fonts_next(void * enum_state,char ** fontname,char ** path)183 int gp_enumerate_fonts_next(void *enum_state, char **fontname, char **path)
184 {
185 return 0;
186 }
187
gp_enumerate_fonts_free(void * enum_state)188 void gp_enumerate_fonts_free(void *enum_state)
189 {
190 }
191