1 | /***************************************************************************
|
---|
2 | * _ _ ____ _
|
---|
3 | * Project ___| | | | _ \| |
|
---|
4 | * / __| | | | |_) | |
|
---|
5 | * | (__| |_| | _ <| |___
|
---|
6 | * \___|\___/|_| \_\_____|
|
---|
7 | *
|
---|
8 | * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
---|
9 | *
|
---|
10 | * This software is licensed as described in the file COPYING, which
|
---|
11 | * you should have received as part of this distribution. The terms
|
---|
12 | * are also available at https://curl.haxx.se/docs/copyright.html.
|
---|
13 | *
|
---|
14 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
---|
15 | * copies of the Software, and permit persons to whom the Software is
|
---|
16 | * furnished to do so, under the terms of the COPYING file.
|
---|
17 | *
|
---|
18 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
---|
19 | * KIND, either express or implied.
|
---|
20 | *
|
---|
21 | ***************************************************************************/
|
---|
22 | #include "tool_setup.h"
|
---|
23 |
|
---|
24 | #ifdef __VMS
|
---|
25 |
|
---|
26 | #if defined(__DECC) && !defined(__VAX) && \
|
---|
27 | defined(__CRTL_VER) && (__CRTL_VER >= 70301000)
|
---|
28 | #include <unixlib.h>
|
---|
29 | #endif
|
---|
30 |
|
---|
31 | #define ENABLE_CURLX_PRINTF
|
---|
32 | #include "curlx.h"
|
---|
33 |
|
---|
34 | #include "curlmsg_vms.h"
|
---|
35 | #include "tool_vms.h"
|
---|
36 |
|
---|
37 | #include "memdebug.h" /* keep this as LAST include */
|
---|
38 |
|
---|
39 | void decc$__posix_exit(int __status);
|
---|
40 | void decc$exit(int __status);
|
---|
41 |
|
---|
42 | static int vms_shell = -1;
|
---|
43 |
|
---|
44 | /* VMS has a DCL shell and and also has Unix shells ported to it.
|
---|
45 | * When curl is running under a Unix shell, we want it to be as much
|
---|
46 | * like Unix as possible.
|
---|
47 | */
|
---|
48 | int is_vms_shell(void)
|
---|
49 | {
|
---|
50 | char *shell;
|
---|
51 |
|
---|
52 | /* Have we checked the shell yet? */
|
---|
53 | if(vms_shell >= 0)
|
---|
54 | return vms_shell;
|
---|
55 |
|
---|
56 | shell = getenv("SHELL");
|
---|
57 |
|
---|
58 | /* No shell, means DCL */
|
---|
59 | if(shell == NULL) {
|
---|
60 | vms_shell = 1;
|
---|
61 | return 1;
|
---|
62 | }
|
---|
63 |
|
---|
64 | /* Have to make sure some one did not set shell to DCL */
|
---|
65 | if(strcmp(shell, "DCL") == 0) {
|
---|
66 | vms_shell = 1;
|
---|
67 | return 1;
|
---|
68 | }
|
---|
69 |
|
---|
70 | vms_shell = 0;
|
---|
71 | return 0;
|
---|
72 | }
|
---|
73 |
|
---|
74 | /*
|
---|
75 | * VMS has two exit() routines. When running under a Unix style shell, then
|
---|
76 | * Unix style and the __posix_exit() routine is used.
|
---|
77 | *
|
---|
78 | * When running under the DCL shell, then the VMS encoded codes and decc$exit()
|
---|
79 | * is used.
|
---|
80 | *
|
---|
81 | * We can not use exit() or return a code from main() because the actual
|
---|
82 | * routine called depends on both the compiler version, compile options, and
|
---|
83 | * feature macro settings, and one of the exit routines is hidden at compile
|
---|
84 | * time.
|
---|
85 | *
|
---|
86 | * Since we want Curl to work properly under the VMS DCL shell and Unix
|
---|
87 | * shells under VMS, this routine should compile correctly regardless of
|
---|
88 | * the settings.
|
---|
89 | */
|
---|
90 |
|
---|
91 | void vms_special_exit(int code, int vms_show)
|
---|
92 | {
|
---|
93 | int vms_code;
|
---|
94 |
|
---|
95 | /* The Posix exit mode is only available after VMS 7.0 */
|
---|
96 | #if __CRTL_VER >= 70000000
|
---|
97 | if(is_vms_shell() == 0) {
|
---|
98 | decc$__posix_exit(code);
|
---|
99 | }
|
---|
100 | #endif
|
---|
101 |
|
---|
102 | if(code > CURL_LAST) { /* If CURL_LAST exceeded then */
|
---|
103 | vms_code = CURL_LAST; /* curlmsg.h is out of sync. */
|
---|
104 | }
|
---|
105 | else {
|
---|
106 | vms_code = vms_cond[code] | vms_show;
|
---|
107 | }
|
---|
108 | decc$exit(vms_code);
|
---|
109 | }
|
---|
110 |
|
---|
111 | #if defined(__DECC) && !defined(__VAX) && \
|
---|
112 | defined(__CRTL_VER) && (__CRTL_VER >= 70301000)
|
---|
113 |
|
---|
114 | /*
|
---|
115 | * 2004-09-19 SMS.
|
---|
116 | *
|
---|
117 | * decc_init()
|
---|
118 | *
|
---|
119 | * On non-VAX systems, use LIB$INITIALIZE to set a collection of C
|
---|
120 | * RTL features without using the DECC$* logical name method, nor
|
---|
121 | * requiring the user to define the corresponding logical names.
|
---|
122 | */
|
---|
123 |
|
---|
124 | /* Structure to hold a DECC$* feature name and its desired value. */
|
---|
125 | typedef struct {
|
---|
126 | char *name;
|
---|
127 | int value;
|
---|
128 | } decc_feat_t;
|
---|
129 |
|
---|
130 | /* Array of DECC$* feature names and their desired values. */
|
---|
131 | static decc_feat_t decc_feat_array[] = {
|
---|
132 | /* Preserve command-line case with SET PROCESS/PARSE_STYLE=EXTENDED */
|
---|
133 | { "DECC$ARGV_PARSE_STYLE", 1 },
|
---|
134 | /* Preserve case for file names on ODS5 disks. */
|
---|
135 | { "DECC$EFS_CASE_PRESERVE", 1 },
|
---|
136 | /* Enable multiple dots (and most characters) in ODS5 file names,
|
---|
137 | while preserving VMS-ness of ";version". */
|
---|
138 | { "DECC$EFS_CHARSET", 1 },
|
---|
139 | /* List terminator. */
|
---|
140 | { (char *)NULL, 0 }
|
---|
141 | };
|
---|
142 |
|
---|
143 | /* Flag to sense if decc_init() was called. */
|
---|
144 | static int decc_init_done = -1;
|
---|
145 |
|
---|
146 | /* LIB$INITIALIZE initialization function. */
|
---|
147 | static void decc_init(void)
|
---|
148 | {
|
---|
149 | int feat_index;
|
---|
150 | int feat_value;
|
---|
151 | int feat_value_max;
|
---|
152 | int feat_value_min;
|
---|
153 | int i;
|
---|
154 | int sts;
|
---|
155 |
|
---|
156 | /* Set the global flag to indicate that LIB$INITIALIZE worked. */
|
---|
157 | decc_init_done = 1;
|
---|
158 |
|
---|
159 | /* Loop through all items in the decc_feat_array[]. */
|
---|
160 | for(i = 0; decc_feat_array[i].name != NULL; i++) {
|
---|
161 |
|
---|
162 | /* Get the feature index. */
|
---|
163 | feat_index = decc$feature_get_index(decc_feat_array[i].name);
|
---|
164 |
|
---|
165 | if(feat_index >= 0) {
|
---|
166 | /* Valid item. Collect its properties. */
|
---|
167 | feat_value = decc$feature_get_value(feat_index, 1);
|
---|
168 | feat_value_min = decc$feature_get_value(feat_index, 2);
|
---|
169 | feat_value_max = decc$feature_get_value(feat_index, 3);
|
---|
170 |
|
---|
171 | if((decc_feat_array[i].value >= feat_value_min) &&
|
---|
172 | (decc_feat_array[i].value <= feat_value_max)) {
|
---|
173 | /* Valid value. Set it if necessary. */
|
---|
174 | if(feat_value != decc_feat_array[i].value) {
|
---|
175 | sts = decc$feature_set_value(feat_index, 1,
|
---|
176 | decc_feat_array[i].value);
|
---|
177 | }
|
---|
178 | }
|
---|
179 | else {
|
---|
180 | /* Invalid DECC feature value. */
|
---|
181 | printf(" INVALID DECC FEATURE VALUE, %d: %d <= %s <= %d.\n",
|
---|
182 | feat_value,
|
---|
183 | feat_value_min, decc_feat_array[i].name, feat_value_max);
|
---|
184 | }
|
---|
185 | }
|
---|
186 | else {
|
---|
187 | /* Invalid DECC feature name. */
|
---|
188 | printf(" UNKNOWN DECC FEATURE: %s.\n", decc_feat_array[i].name);
|
---|
189 | }
|
---|
190 |
|
---|
191 | }
|
---|
192 | }
|
---|
193 |
|
---|
194 | /* Get "decc_init()" into a valid, loaded LIB$INITIALIZE PSECT. */
|
---|
195 |
|
---|
196 | #pragma nostandard
|
---|
197 |
|
---|
198 | /* Establish the LIB$INITIALIZE PSECTs, with proper alignment and
|
---|
199 | other attributes. Note that "nopic" is significant only on VAX. */
|
---|
200 | #pragma extern_model save
|
---|
201 | #pragma extern_model strict_refdef "LIB$INITIALIZ" 2, nopic, nowrt
|
---|
202 | const int spare[8] = {0};
|
---|
203 | #pragma extern_model strict_refdef "LIB$INITIALIZE" 2, nopic, nowrt
|
---|
204 | void (*const x_decc_init)() = decc_init;
|
---|
205 | #pragma extern_model restore
|
---|
206 |
|
---|
207 | /* Fake reference to ensure loading the LIB$INITIALIZE PSECT. */
|
---|
208 | #pragma extern_model save
|
---|
209 | int LIB$INITIALIZE(void);
|
---|
210 | #pragma extern_model strict_refdef
|
---|
211 | int dmy_lib$initialize = (int) LIB$INITIALIZE;
|
---|
212 | #pragma extern_model restore
|
---|
213 |
|
---|
214 | #pragma standard
|
---|
215 |
|
---|
216 | #endif /* __DECC && !__VAX && __CRTL_VER && __CRTL_VER >= 70301000 */
|
---|
217 |
|
---|
218 | #endif /* __VMS */
|
---|
219 |
|
---|