1 /* openclose.c: open and close files for TeX, Metafont, and BibTeX.
3 Written 1995 Karl Berry. Public domain. */
5 #include <w2c/config.h>
7 #include <kpathsea/c-pathch.h>
8 #include <kpathsea/tex-file.h>
9 #include <kpathsea/variable.h>
10 #include <kpathsea/absolute.h>
12 #include <ptexenc/ptexenc.h>
18 #define fopen fsyscp_fopen
19 #define xfopen fsyscp_xfopen
22 /* The globals we use to communicate. */
23 extern string nameoffile
;
24 extern unsigned namelength
;
26 /* Define some variables. */
27 /* For "file:line:error" style error messages. */
28 string fullnameoffile
; /* Defaults to NULL. */
29 static string recorder_name
; /* Defaults to NULL. */
30 static FILE *recorder_file
; /* Defaults to NULL. */
31 /* For the filename recorder. */
32 boolean recorder_enabled
; /* Defaults to false. */
33 /* For the output-dir option. */
34 string output_directory
; /* Defaults to NULL. */
36 /* For TeX and MetaPost. See below. Always defined so we don't have to
37 #ifdef, and thus this file can be compiled once and go in lib.a. */
42 /* Helpers for the filename recorder... */
43 /* Start the recorder */
47 /* Alas, while we'd like to use mkstemp it is not portable,
48 and doing the autoconfiscation (and providing fallbacks) is more
49 than we want to cope with. So we have to be content with using a
50 default name. Throw in the pid so at least parallel builds might
51 work (Debian bug 575731). */
53 char pid_str
[MAX_INT_LENGTH
];
55 /* Windows (MSVC) seems to have no pid_t, so instead of storing the
56 value returned by getpid() we immediately consume it. */
57 sprintf (pid_str
, "%ld", (long) getpid());
58 recorder_name
= concat3(kpse_program_name
, pid_str
, ".fls");
60 /* If an output directory was specified, use it instead of cwd. */
61 if (output_directory
) {
62 string temp
= concat3(output_directory
, DIR_SEP_STRING
, recorder_name
);
67 recorder_file
= xfopen(recorder_name
, FOPEN_W_MODE
);
70 fprintf(recorder_file
, "PWD %s\n", cwd
);
74 /* Change the name of the recorder file after we know the log file to
75 the usual thing -- no pid integer and the document file name instead
76 of the program name. Unfortunately, we have to explicitly take
77 -output-directory into account (again), since the NEW_NAME we are
78 called with does not; it is just the log file name with .log replaced
82 recorder_change_filename (string new_name
)
89 /* On windows, an opened file cannot be renamed. */
91 fclose (recorder_file
);
94 /* If an output directory was specified, use it. */
95 if (output_directory
) {
96 temp
= concat3(output_directory
, DIR_SEP_STRING
, new_name
);
100 /* On windows, renaming fails if a file with new_name exists. */
105 rename(recorder_name
, new_name
);
107 recorder_name
= xstrdup(new_name
);
109 /* reopen the recorder file by FOPEN_A_MODE. */
111 recorder_file
= fsyscp_xfopen (recorder_name
, FOPEN_A_MODE
);
118 /* helper for recorder_record_* */
120 recorder_record_name (const_string prefix
, const_string name
)
122 if (recorder_enabled
) {
125 fprintf(recorder_file
, "%s %s\n", prefix
, name
);
126 fflush(recorder_file
);
130 /* record an input file name */
132 recorder_record_input (const_string name
)
134 recorder_record_name ("INPUT", name
);
137 /* record an output file name */
139 recorder_record_output (const_string name
)
141 recorder_record_name ("OUTPUT", name
);
144 /* Open an input file F, using the kpathsea format FILEFMT and passing
145 FOPEN_MODE to fopen. The filename is in `nameoffile+1'. We return
146 whether or not the open succeeded. If it did, `nameoffile' is set to
147 the full filename opened, and `namelength' to its length. */
150 open_input (FILE **f_ptr
, int filefmt
, const_string fopen_mode
)
153 #ifdef FUNNY_CORE_DUMP
154 /* This only applies if a preloaded TeX/Metafont is being made;
155 it allows automatic creation of the core dump (typing ^\ loses
156 since that requires manual intervention). */
157 if ((filefmt
== kpse_tex_format
|| filefmt
== kpse_mf_format
158 || filefmt
== kpse_mp_format
)
159 && STREQ (nameoffile
+ 1, "HackyInputFileNameForCoreDump.tex"))
163 /* We havent found anything yet. */
166 free(fullnameoffile
);
167 fullnameoffile
= NULL
;
169 /* Look in -output-directory first, if the filename is not
170 absolute. This is because .aux and other such files will get
171 written to the output directory, and we have to be able to read
172 them from there. We only look for the name as-is. */
173 if (output_directory
&& !kpse_absolute_p (nameoffile
+1, false)) {
174 fname
= concat3 (output_directory
, DIR_SEP_STRING
, nameoffile
+ 1);
175 *f_ptr
= fopen (fname
, fopen_mode
);
178 namelength
= strlen (fname
);
179 nameoffile
= xmalloc (namelength
+ 2);
180 strcpy (nameoffile
+ 1, fname
);
181 fullnameoffile
= fname
;
187 /* No file means do the normal search. */
188 if (*f_ptr
== NULL
) {
189 /* A negative FILEFMT means don't use a path. */
191 /* no_file_path, for BibTeX .aux files and MetaPost things. */
192 *f_ptr
= fopen(nameoffile
+ 1, fopen_mode
);
193 /* FIXME... fullnameoffile = xstrdup(nameoffile + 1); */
195 /* The only exception to `must_exist' being true is \openin, for
196 which we set `tex_input_type' to 0 in the change file. */
197 /* According to the pdfTeX people, pounding the disk for .vf files
198 is overkill as well. A more general solution would be nice. */
199 boolean must_exist
= (filefmt
!= kpse_tex_format
|| texinputtype
)
200 && (filefmt
!= kpse_vf_format
);
201 fname
= kpse_find_file (nameoffile
+ 1,
202 (kpse_file_format_type
)filefmt
,
205 fullnameoffile
= xstrdup(fname
);
206 /* If we found the file in the current directory, don't leave
207 the `./' at the beginning of `nameoffile', since it looks
208 dumb when `tex foo' says `(./foo.tex ... )'. On the other
209 hand, if the user said `tex ./foo', and that's what we
210 opened, then keep it -- the user specified it, so we
211 shouldn't remove it. */
212 if (fname
[0] == '.' && IS_DIR_SEP (fname
[1])
213 && (nameoffile
[1] != '.' || !IS_DIR_SEP (nameoffile
[2])))
216 while (fname
[i
+ 2] != 0) {
217 fname
[i
] = fname
[i
+ 2];
223 /* kpse_find_file always returns a new string. */
225 namelength
= strlen (fname
);
226 nameoffile
= xmalloc (namelength
+ 2);
227 strcpy (nameoffile
+ 1, fname
);
230 /* This fopen is not allowed to fail. */
231 #if defined(PTEX) && !defined(WIN32)
232 if (filefmt
== kpse_tex_format
||
233 filefmt
== kpse_bib_format
) {
234 *f_ptr
= nkf_open (nameoffile
+ 1, fopen_mode
);
237 *f_ptr
= xfopen (nameoffile
+ 1, fopen_mode
);
243 recorder_record_input (nameoffile
+ 1);
245 /* If we just opened a TFM file, we have to read the first
246 byte, to pretend we're Pascal. See tex.ch and mp.ch.
247 Ditto for the ocp/ofm Omega file formats. */
248 if (filefmt
== kpse_tfm_format
) {
249 tfmtemp
= getc (*f_ptr
);
250 /* We intentionally do not check for EOF here, i.e., an
251 empty TFM file. TeX will see the 255 byte and complain
252 about a bad TFM file, which is what we want. */
253 } else if (filefmt
== kpse_ocp_format
) {
254 ocptemp
= getc (*f_ptr
);
255 } else if (filefmt
== kpse_ofm_format
) {
256 tfmtemp
= getc (*f_ptr
);
260 return *f_ptr
!= NULL
;
263 /* Open an output file F either in the current directory or in
264 $TEXMFOUTPUT/F, if the environment variable `TEXMFOUTPUT' exists.
265 (Actually, this also applies to the BibTeX and MetaPost output files,
266 but `TEXMFMPBIBOUTPUT' was just too long.) The filename is in the
267 global `nameoffile' + 1. We return whether or not the open
268 succeeded. If it did, `nameoffile' is reset to the name opened if
269 necessary, and `namelength' to its length. */
272 open_output (FILE **f_ptr
, const_string fopen_mode
)
275 boolean absolute
= kpse_absolute_p(nameoffile
+1, false);
277 /* If we have an explicit output directory, use it. */
278 if (output_directory
&& !absolute
) {
279 fname
= concat3(output_directory
, DIR_SEP_STRING
, nameoffile
+ 1);
281 fname
= nameoffile
+ 1;
284 /* Is the filename openable as given? */
285 *f_ptr
= fopen (fname
, fopen_mode
);
288 /* Can't open as given. Try the envvar. */
289 string texmfoutput
= kpse_var_value("TEXMFOUTPUT");
291 if (texmfoutput
&& *texmfoutput
&& !absolute
) {
292 if (fname
!= nameoffile
+ 1)
294 fname
= concat3(texmfoutput
, DIR_SEP_STRING
, nameoffile
+1);
295 *f_ptr
= fopen(fname
, fopen_mode
);
298 /* If this succeeded, change nameoffile accordingly. */
300 if (fname
!= nameoffile
+ 1) {
302 namelength
= strlen (fname
);
303 nameoffile
= xmalloc (namelength
+ 2);
304 strcpy (nameoffile
+ 1, fname
);
306 recorder_record_output (fname
);
308 if (fname
!= nameoffile
+1)
310 return *f_ptr
!= NULL
;
318 /* If F is null, just return. bad_pool might close a file that has
319 never been opened. */
325 clear_infile_enc (f
);
326 if (fclose (f
) == EOF
) {
328 if (nkf_close (f
) == EOF
) {
331 if (fclose (f
) == EOF
) {
333 /* It's not always nameoffile, we might have opened something else
334 in the meantime. And it's not easy to extract the filenames out
335 of the pool array. So just punt on the filename. Sigh. This
336 probably doesn't need to be a fatal error. */