source: trunk/essentials/sys-devel/m4/lib/tmpdir.c

Last change on this file was 3090, checked in by bird, 18 years ago

m4 1.4.8

File size: 3.3 KB
Line 
1/* Copyright (C) 1999, 2001-2002, 2006 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software Foundation,
16 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
17
18/* Extracted from sysdeps/posix/tempname.c. */
19
20#include <config.h>
21
22/* Specification. */
23#include "tmpdir.h"
24
25#include <stdbool.h>
26#include <stdlib.h>
27#include <string.h>
28
29#include <errno.h>
30#ifndef __set_errno
31# define __set_errno(Val) errno = (Val)
32#endif
33
34#include <stdio.h>
35#ifndef P_tmpdir
36# define P_tmpdir "/tmp"
37#endif
38
39#include <sys/stat.h>
40
41#if _LIBC
42# define struct_stat64 struct stat64
43#else
44# define struct_stat64 struct stat
45# define __xstat64(version, path, buf) stat (path, buf)
46#endif
47
48#if ! (HAVE___SECURE_GETENV || _LIBC)
49# define __secure_getenv getenv
50#endif
51
52/* Pathname support.
53 ISSLASH(C) tests whether C is a directory separator character.
54 */
55#if defined _WIN32 || defined __WIN32__ || defined __CYGWIN__ || defined __EMX__ || defined __DJGPP__
56 /* Win32, Cygwin, OS/2, DOS */
57# define ISSLASH(C) ((C) == '/' || (C) == '\\')
58#else
59 /* Unix */
60# define ISSLASH(C) ((C) == '/')
61#endif
62
63
64/* Return nonzero if DIR is an existent directory. */
65static bool
66direxists (const char *dir)
67{
68 struct_stat64 buf;
69 return __xstat64 (_STAT_VER, dir, &buf) == 0 && S_ISDIR (buf.st_mode);
70}
71
72/* Path search algorithm, for tmpnam, tmpfile, etc. If DIR is
73 non-null and exists, uses it; otherwise uses the first of $TMPDIR,
74 P_tmpdir, /tmp that exists. Copies into TMPL a template suitable
75 for use with mk[s]temp. Will fail (-1) if DIR is non-null and
76 doesn't exist, none of the searched dirs exists, or there's not
77 enough space in TMPL. */
78int
79path_search (char *tmpl, size_t tmpl_len, const char *dir, const char *pfx,
80 bool try_tmpdir)
81{
82 const char *d;
83 size_t dlen, plen;
84
85 if (!pfx || !pfx[0])
86 {
87 pfx = "file";
88 plen = 4;
89 }
90 else
91 {
92 plen = strlen (pfx);
93 if (plen > 5)
94 plen = 5;
95 }
96
97 if (try_tmpdir)
98 {
99 d = __secure_getenv ("TMPDIR");
100 if (d != NULL && direxists (d))
101 dir = d;
102 else if (dir != NULL && direxists (dir))
103 /* nothing */ ;
104 else
105 dir = NULL;
106 }
107 if (dir == NULL)
108 {
109 if (direxists (P_tmpdir))
110 dir = P_tmpdir;
111 else if (strcmp (P_tmpdir, "/tmp") != 0 && direxists ("/tmp"))
112 dir = "/tmp";
113 else
114 {
115 __set_errno (ENOENT);
116 return -1;
117 }
118 }
119
120 dlen = strlen (dir);
121 while (dlen >= 1 && ISSLASH (dir[dlen - 1]))
122 dlen--; /* remove trailing slashes */
123
124 /* check we have room for "${dir}/${pfx}XXXXXX\0" */
125 if (tmpl_len < dlen + 1 + plen + 6 + 1)
126 {
127 __set_errno (EINVAL);
128 return -1;
129 }
130
131 sprintf (tmpl, "%.*s/%.*sXXXXXX", (int) dlen, dir, (int) plen, pfx);
132 return 0;
133}
Note: See TracBrowser for help on using the repository browser.