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 5 This file is part of groff. 6 7 groff is free software; you can redistribute it and/or modify it under 8 the terms of the GNU General Public License as published by the Free 9 Software Foundation; either version 2, or (at your option) any later 10 version. 11 12 groff is distributed in the hope that it will be useful, but WITHOUT ANY 13 WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 for more details. 16 17 You should have received a copy of the GNU General Public License along 18 with groff; see the file COPYING. If not, write to the Free Software 19 Foundation, 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