* src/include/lib.h: Added xtmptemplate and made xtmpfile
[s-roff.git] / src / libs / libgroff / tmpfile.cc
blob6d5ea7c1851373f961706fc3c3d81b5f14e266d9
1 // -*- C++ -*-
2 /* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
3 Written by James Clark (jjc@jclark.com)
5 This file is part of groff.
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.
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.
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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21 #include <stdio.h>
22 #include <errno.h>
23 #include <string.h>
24 #include <stdlib.h>
26 #include "posix.h"
27 #include "lib.h"
28 #include "errarg.h"
29 #include "error.h"
31 extern "C" {
32 // Sun's stdlib.h fails to declare this.
33 char *mktemp(char *);
34 int mkstemp(char *);
37 // If this is set, create temporary files there
38 #define GROFF_TMPDIR_ENVVAR "GROFF_TMPDIR"
39 // otherwise if this is set, create temporary files there
40 #define TMPDIR_ENVVAR "TMPDIR"
41 // otherwise create temporary files here.
42 #define DEFAULT_TMPDIR "/tmp"
43 // Use this as the prefix for temporary filenames.
44 #define TMPFILE_PREFIX "groff"
47 * Generate a temporary name template with a postfix
48 * immediately after the TMPFILE_PREFIX.
49 * It uses the groff preferences for a temporary directory.
50 * Note that no file name is either created or opened,
51 * only the *template* is returned.
54 char *xtmptemplate(char *postfix=0)
56 const char *dir = getenv(GROFF_TMPDIR_ENVVAR);
57 int postlen = 0;
59 if (postfix)
60 postlen = strlen(postfix);
62 if (!dir) {
63 dir = getenv(TMPDIR_ENVVAR);
64 if (!dir)
65 dir = DEFAULT_TMPDIR;
68 const char *p = strrchr(dir, '/');
69 int needs_slash = (!p || p[1]);
70 char *templ = new char[strlen(dir) + needs_slash
71 + sizeof(TMPFILE_PREFIX) - 1 + 6 + 1 + postlen];
72 strcpy(templ, dir);
73 if (needs_slash)
74 strcat(templ, "/");
75 strcat(templ, TMPFILE_PREFIX);
76 if (postlen > 0)
77 strcat(templ, postfix);
78 strcat(templ, "XXXXXX");
80 return( templ );
83 // Open a temporary file and with fatal error on failure.
85 FILE *xtmpfile(char **namep=0, char *postfix=0, int do_unlink=1)
87 char *templ = xtmptemplate(postfix);
89 #ifdef HAVE_MKSTEMP
90 errno = 0;
91 int fd = mkstemp(templ);
92 if (fd < 0)
93 fatal("cannot create temporary file: %1", strerror(errno));
94 errno = 0;
95 FILE *fp = fdopen(fd, "w+");
96 if (!fp)
97 fatal("fdopen: %1", strerror(errno));
98 #else /* not HAVE_MKSTEMP */
99 if (!mktemp(templ) || !templ[0])
100 fatal("cannot create file name for temporary file");
101 errno = 0;
102 FILE *fp = fopen(templ, "w+");
103 if (!fp)
104 fatal("cannot open `%1': %2", templ, strerror(errno));
105 #endif /* not HAVE_MKSTEMP */
106 if ((do_unlink) && (unlink(templ) < 0))
107 error("cannot unlink `%1': %2", templ, strerror(errno));
108 if ((namep != 0) && ((*namep) != 0)) {
109 *namep = templ;
110 } else {
111 a_delete templ;
113 return fp;
116 #if 0
117 // If you're not running Unix, the following will do:
118 FILE *xtmpfile(char **namep, char *postfix=0, int do_unlink=1)
120 FILE *fp = tmpfile();
121 if (!fp)
122 fatal("couldn't create temporary file");
123 return fp;
125 #endif