1/* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005
2   Free Software Foundation, Inc.
3     Written by Eli Zaretskii (eliz@is.elta.co.il)
4
5This file is part of groff.
6
7groff is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 2, or (at your option) any later
10version.
11
12groff is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License along
18with groff; see the file COPYING.  If not, write to the Free Software
19Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
20
21/* This header file compartmentalize all idiosyncrasies of non-Posix
22   systems, such as MS-DOS, MS-Windows, etc.  It should be loaded after
23   the system headers like stdio.h to protect against warnings and error
24   messages w.r.t. redefining macros. */
25
26#if defined _MSC_VER
27# ifndef _WIN32
28#  define _WIN32
29# endif
30#endif
31
32#if defined(__MSDOS__) || defined(__EMX__) \
33    || (defined(_WIN32) && !defined(_UWIN) && !defined(__CYGWIN__))
34
35/* Binary I/O nuisances. */
36# include <fcntl.h>
37# include <io.h>
38# ifdef HAVE_UNISTD_H
39#  include <unistd.h>
40# endif
41# ifndef STDIN_FILENO
42#  define STDIN_FILENO	0
43#  define STDOUT_FILENO	1
44#  define STDERR_FILENO	2
45# endif
46# ifdef HAVE_DIRECT_H
47#  include <direct.h>
48# endif
49# ifdef HAVE_PROCESS_H
50#  include <process.h>
51# endif
52# if defined(_MSC_VER) || defined(__MINGW32__)
53#  define POPEN_RT	"rt"
54#  define POPEN_WT	"wt"
55#  define popen(c,m)	_popen(c,m)
56#  define pclose(p)	_pclose(p)
57#  define pipe(pfd)	_pipe((pfd),0,_O_BINARY|_O_NOINHERIT)
58#  define mkdir(p,m)	_mkdir(p)
59#  define setmode(f,m)	_setmode(f,m)
60#  define WAIT(s,p,m)	_cwait(s,p,m)
61#  define creat(p,m)	_creat(p,m)
62#  define read(f,b,s)	_read(f,b,s)
63#  define write(f,b,s)	_write(f,b,s)
64#  define dup(f)	_dup(f)
65#  define dup2(f1,f2)	_dup2(f1,f2)
66#  define close(f)	_close(f)
67#  define isatty(f)	_isatty(f)
68#  define access(p,m)	_access(p,m)
69# endif
70# define SET_BINARY(f)	do {if (!isatty(f)) setmode(f,O_BINARY);} while(0)
71# define FOPEN_RB	"rb"
72# define FOPEN_WB	"wb"
73# define FOPEN_RWB	"wb+"
74# ifndef O_BINARY
75#  ifdef _O_BINARY
76#   define O_BINARY	(_O_BINARY)
77#  endif
78# endif
79
80/* The system shell.  Groff assumes a Unixy shell, but non-Posix
81   systems don't have standard places where it lives, and might not
82   have it installed to begin with.  We want to give them some leeway.  */
83# ifdef __EMX__
84#  define getcwd(b,s)	_getcwd2(b,s)
85# else
86#  define BSHELL	(system_shell_name())
87#  define BSHELL_DASH_C	(system_shell_dash_c())
88#  define IS_BSHELL(s)	(is_system_shell(s))
89# endif
90
91/* The separator for directories in PATH and other environment
92   variables.  */
93# define PATH_SEP	";"
94# define PATH_SEP_CHAR	';'
95
96/* Characters that separate directories in a path name.  */
97# define DIR_SEPS	"/\\:"
98
99/* How to tell if the argument is an absolute file name.  */
100# define IS_ABSOLUTE(f) \
101 ((f)[0] == '/' || (f)[0] == '\\' || (f)[0] && (f)[1] == ':')
102
103/* The executable extension.  */
104# define EXE_EXT	".exe"
105
106/* Possible executable extensions.  */
107# define PATH_EXT	".com;.exe;.bat;.cmd"
108
109/* The system null device.  */
110# define NULL_DEV	"NUL"
111
112/* The default place to create temporary files.  */
113# ifndef P_tmpdir
114#  ifdef _P_tmpdir
115#   define P_tmpdir	_P_tmpdir
116#  else
117#   define P_tmpdir	"c:/temp"
118#  endif
119# endif
120
121/* Prototypes.  */
122# ifdef __cplusplus
123  extern "C" {
124# endif
125    char       * system_shell_name(void);
126    const char * system_shell_dash_c(void);
127    int		 is_system_shell(const char *);
128# ifdef __cplusplus
129  }
130# endif
131
132#endif
133
134#if defined(_WIN32) && !defined(_UWIN) && !defined(__CYGWIN__)
135/* Win32 implementations which use the Microsoft runtime library
136 * are prone to hanging when a pipe reader quits with unread data in the pipe.
137 * `gtroff' avoids this, by invoking `FLUSH_INPUT_PIPE()', defined as ... */
138# define FLUSH_INPUT_PIPE(fd)		      \
139 do if (!isatty(fd))			      \
140 {					      \
141   char drain[BUFSIZ];			      \
142   while (read(fd, drain, sizeof(drain)) > 0) \
143     ;					      \
144 } while (0)
145
146/* The Microsoft runtime library also has a broken argument passing mechanism,
147 * which may result in improper grouping of arguments passed to a child process
148 * by the `spawn()' family of functions.  In `groff', only the `spawnvp()'
149 * function is affected; we work around this defect, by substituting a
150 * wrapper function in place of `spawnvp()' calls. */
151
152# ifdef __cplusplus
153  extern "C" {
154# endif
155  int spawnvp_wrapper(int, char *, char **);
156# ifdef __cplusplus
157  }
158# endif
159# ifndef SPAWN_FUNCTION_WRAPPERS
160#  undef  spawnvp
161#  define spawnvp      spawnvp_wrapper
162#  undef  _spawnvp
163#  define _spawnvp     spawnvp
164# endif /* SPAWN_FUNCTION_WRAPPERS */
165
166#else
167/* Other implementations do not suffer from Microsoft runtime bugs,
168 * but `gtroff' requires a dummy definition for FLUSH_INPUT_PIPE() */
169# define FLUSH_INPUT_PIPE(fd)	do {} while(0)
170#endif
171
172/* Defaults, for Posix systems.  */
173
174#ifndef SET_BINARY
175# define SET_BINARY(f)	do {} while(0)
176#endif
177#ifndef FOPEN_RB
178# define FOPEN_RB	"r"
179#endif
180#ifndef FOPEN_WB
181# define FOPEN_WB	"w"
182#endif
183#ifndef FOPEN_RWB
184# define FOPEN_RWB	"w+"
185#endif
186#ifndef POPEN_RT
187# define POPEN_RT	"r"
188#endif
189#ifndef POPEN_WT
190# define POPEN_WT	"w"
191#endif
192#ifndef O_BINARY
193# define O_BINARY	0
194#endif
195#ifndef BSHELL
196# define BSHELL		"/bin/sh"
197#endif
198#ifndef BSHELL_DASH_C
199# define BSHELL_DASH_C	"-c"
200#endif
201#ifndef IS_BSHELL
202# define IS_BSHELL(s)	((s) && strcmp(s,BSHELL) == 0)
203#endif
204#ifndef PATH_SEP
205# define PATH_SEP	":"
206# define PATH_SEP_CHAR	':'
207#endif
208#ifndef DIR_SEPS
209# define DIR_SEPS	"/"
210#endif
211#ifndef IS_ABSOLUTE
212# define IS_ABSOLUTE(f)	((f)[0] == '/')
213#endif
214#ifndef EXE_EXT
215# define EXE_EXT	""
216#endif
217#ifndef PATH_EXT
218# define PATH_EXT	""
219#endif
220#ifndef NULL_DEV
221# define NULL_DEV	"/dev/null"
222#endif
223#ifndef GS_NAME
224# define GS_NAME	"gs"
225#endif
226#ifndef WAIT
227# define WAIT(s,p,m)	wait(s)
228#endif
229#ifndef _WAIT_CHILD
230# define _WAIT_CHILD	0
231#endif
232