]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/tools/build/src/engine/pathvms.cpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / tools / build / src / engine / pathvms.cpp
1 /*
2 * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
3 *
4 * This file is part of Jam - see jam.c for Copyright information.
5 */
6
7 /* This file is ALSO:
8 * Copyright 2001-2004 David Abrahams.
9 * Copyright 2005 Rene Rivera.
10 * Copyright 2015 Artur Shepilko.
11 * Distributed under the Boost Software License, Version 1.0.
12 * (See accompanying file LICENSE_1_0.txt or copy at
13 * http://www.boost.org/LICENSE_1_0.txt)
14 */
15
16
17 /*
18 * pathvms.c - VMS-specific path manipulation support
19 *
20 * This implementation is based on POSIX-style path manipulation.
21 *
22 * VMS CTRL directly supports both POSIX- and native VMS-style path expressions,
23 * with the POSIX-to-VMS path translation performed internally by the same
24 * set of functions. For the most part such processing is transparent, with
25 * few differences mainly related to file-versions (in POSIX mode only the recent
26 * version is visible).
27 *
28 * This should allow us to some extent re-use pathunix.c implementation.
29 *
30 * Thus in jam-files the path references can also remain POSIX/UNIX-like on all
31 * levels EXCEPT in actions scope, where the path references must be translated
32 * to the native VMS-style. This approach is somewhat similar to jam CYGWIN
33 * handling.
34 *
35 *
36 * External routines:
37 * path_register_key()
38 * path_as_key()
39 * path_done()
40 *
41 * External routines called only via routines in pathsys.c:
42 * path_get_process_id_()
43 * path_get_temp_path_()
44 * path_translate_to_os_()
45 */
46
47
48 #include "jam.h"
49
50 #ifdef OS_VMS
51
52 #include "pathsys.h"
53
54 #include <assert.h>
55 #include <stdlib.h>
56 #include <unistd.h> /* needed for getpid() */
57 #include <unixlib.h> /* needed for decc$to_vms() */
58
59
60 /*
61 * path_get_process_id_()
62 */
63
64 unsigned long path_get_process_id_( void )
65 {
66 return getpid();
67 }
68
69
70 /*
71 * path_get_temp_path_()
72 */
73
74 void path_get_temp_path_( string * buffer )
75 {
76 char const * t = getenv( "TMPDIR" );
77 string_append( buffer, t ? t : "/tmp" );
78 }
79
80
81 /*
82 * translate_path_posix2vms()
83 *
84 * POSIX-to-VMS file specification translation:
85 *
86 * Translation is performed with decc$to_vms() CTRL routine (default decc$features)
87 * Some limitations apply:
88 * -- ODS-2 compliant file specs only (no spaces, punctuation chars etc.)
89 *
90 * -- wild-cards are not allowed
91 * In general decc$to_vms() can expand the wildcard for existing files,
92 * yet it cannot retain wild-cards in translated spec. Use GLOB for this.
93 *
94 * -- rooted path must refer to an existing/defined device or root-dir
95 * (e.g. /defconcealed/dir/file.ext or /existingrootdir/dir/file.ext )
96 *
97 * -- POSIX dir/no-type-file path ambiguity (e.g. dir/newsubdir vs. dir/newfile
98 * is handled as follows:
99 *
100 * 1) first try as directory:
101 * -- if translated (may be a dir): means the file-path has no .type/suffix
102 * -- if not translated, then it may be a file (has .type) OR invalid spec
103 * 2) then try as file:
104 * -- if translated and also is a dir -- check if such file exists (stat)
105 * -- if not translated, but is a dir -- return as dir
106 *
107 * NOTE: on VMS it's possible to have both a file and a dir of the same name
108 * appear in the same directory. In such case _directory_ intent is assumed.
109 *
110 * It's preferable to avoid such naming ambiguity in this context, so
111 * append an empty .type to specify a no-type file (eg. "filename.")
112 *
113 */
114
115
116 static string * m_vmsfilespec = NULL;
117
118 /*
119 * copy_vmsfilespec() - decc$to_vms action routine for matched filenames
120 */
121
122 static int copy_vmsfilespec( char * f, int type )
123 {
124 assert ( NULL != m_vmsfilespec && "Must be bound to a valid object" );
125
126 string_copy( m_vmsfilespec, f );
127
128 /* 0:Exit on first match (1:Process all) */
129 return 0;
130 }
131
132
133 static int translate_path_posix2vms( string * path )
134 {
135 int translated = 0;
136
137 string as_dir[ 1 ];
138 string as_file[ 1 ];
139 int dir_count;
140 int file_count;
141
142 unsigned char is_dir;
143 unsigned char is_file;
144 unsigned char is_ambiguous;
145
146 string_new( as_dir );
147 string_new( as_file );
148
149
150 m_vmsfilespec = as_dir;
151
152 /* MATCH 0:do not allow wildcards, 0:allow directories (2:dir only) */
153 dir_count = decc$to_vms( path->value, copy_vmsfilespec, 0, 2 );
154
155
156 m_vmsfilespec = as_file;
157
158 /* MATCH 0:do not allow wildcards, 0:allow directories (2:dir only) */
159 file_count = decc$to_vms( path->value, copy_vmsfilespec, 0, 0 );
160
161 m_vmsfilespec = NULL;
162
163
164 translated = ( file_count || dir_count );
165
166 if ( file_count && dir_count )
167 {
168 struct stat statbuf;
169
170 /* use as_file only when exists AND as_dir does not exist
171 * otherwise use as_dir
172 */
173 if ( stat(as_dir->value, &statbuf ) < 0
174 && stat(as_file->value, &statbuf ) > 0
175 && ( statbuf.st_mode & S_IFREG ) )
176 {
177 string_truncate( path, 0 );
178 string_append( path, as_file->value );
179 }
180 else
181 {
182 string_truncate( path, 0 );
183 string_append( path, as_dir->value );
184 }
185 }
186 else if ( file_count )
187 {
188 string_truncate( path, 0 );
189 string_append( path, as_file->value );
190 }
191 else if ( dir_count )
192 {
193 string_truncate( path, 0 );
194 string_append( path, as_dir->value );
195 }
196 else
197 {
198 /* error: unable to translate path to native format */
199 translated = 0;
200 }
201
202 string_free( as_dir );
203 string_free( as_file );
204
205 return translated;
206 }
207
208
209 /*
210 * path_translate_to_os_()
211 */
212
213 int path_translate_to_os_( char const * f, string * file )
214 {
215 int translated = 0;
216
217 /* by default, pass on the original path */
218 string_copy( file, f );
219
220 translated = translate_path_posix2vms( file );
221
222 return translated;
223 }
224
225
226 /*
227 * path_register_key()
228 */
229
230 void path_register_key( OBJECT * path )
231 {
232 }
233
234
235 /*
236 * path_as_key()
237 */
238
239 OBJECT * path_as_key( OBJECT * path )
240 {
241 return object_copy( path );
242 }
243
244
245 /*
246 * path_done()
247 */
248
249 void path_done( void )
250 {
251 }
252
253 #endif
254