This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Merge the implementation of B::{main_root,main_start} using ALIAS.
[perl5.git] / vos / vos.c
CommitLineData
7b2b351e
PG
1/* Beginning of modification history */
2/* Written 02-01-02 by Nick Ing-Simmons (nick@ing-simmons.net) */
a5f25d7a
PG
3/* Modified 02-03-27 by Paul Green (Paul.Green@stratus.com) to
4 add socketpair() dummy. */
0ee4199b
PG
5/* Modified 02-04-24 by Paul Green (Paul.Green@stratus.com) to
6 have pow(0,0) return 1, avoiding c-1471. */
dab8accc
PG
7/* Modified 06-09-25 by Paul Green (Paul.Green@stratus.com) to
8 add syslog entries. */
3722f0dc
PG
9/* Modified 08-02-04 by Paul Green (Paul.Green@stratus.com) to
10 open the syslog file in the working dir. */
7b2b351e
PG
11/* End of modification history */
12
a5f25d7a 13#include <errno.h>
7b2b351e 14#include <fcntl.h>
dab8accc
PG
15#include <stdio.h>
16#include <stdlib.h>
17#include <string.h>
7b2b351e
PG
18#include <sys/types.h>
19#include <unistd.h>
20
dab8accc
PG
21#include "vos/syslog.h"
22
a5f25d7a
PG
23/* VOS doesn't supply a truncate function, so we build one up
24 from the available POSIX functions. */
25
7b2b351e
PG
26int
27truncate(const char *path, off_t len)
28{
29 int fd = open(path,O_WRONLY);
30 int code = -1;
31 if (fd >= 0) {
32 code = ftruncate(fd,len);
33 close(fd);
34 }
35 return code;
36}
a5f25d7a
PG
37
38/* VOS doesn't implement AF_UNIX (AF_LOCAL) style sockets, and
39 the perl emulation of them hangs on VOS (due to stcp-1257),
40 so we supply this version that always fails. */
41
42int
43socketpair (int family, int type, int protocol, int fd[2]) {
44 fd[0] = 0;
45 fd[1] = 0;
46 errno = ENOSYS;
47 return -1;
48}
0ee4199b
PG
49
50/* Supply a private version of the power function that returns 1
51 for x**0. This avoids c-1471. Abigail's Japh tests depend
52 on this fix. We leave all the other cases to the VOS C
53 runtime. */
54
55double s_crt_pow(double *x, double *y);
56
57double pow(x,y)
58double x, y;
59{
60 if (y == 0e0) /* c-1471 */
61 {
62 errno = EDOM;
63 return (1e0);
64 }
65
66 return(s_crt_pow(&x,&y));
67}
dab8accc
PG
68
69/* entries */
70
71extern void s$log_system_message (
72/* char_varying (256) *message_text,
73 char_varying (66) *module_name,
74 short int *error_code */ );
75
76/* constants */
77
78#define ALL_PRIORITIES 255 /* 8 priorities, all enabled */
79#define BUFFER_LEN 256
80#define IDENT_LEN 64
81#define MSG_LEN 256
82#define PATH_LEN 257
83
84/* static */
85
86int vos_syslog_facility = LOG_USER>>3;
87int vos_syslog_fd = -1;
88int vos_syslog_logopt = 0;
89char vos_syslog_ident[IDENT_LEN] = "";
90int vos_syslog_ident_len = 0;
91int vos_syslog_mask = ALL_PRIORITIES;
3722f0dc 92char vos_syslog_path[PATH_LEN] = "syslog";
dab8accc
PG
93
94char vos_syslog_facility_name [17][10] = {
95 "[KERN] ", /* LOG_KERN */
96 "[USER] ", /* LOG_USER */
97 "[MAIL] ", /* LOG_MAIL */
98 "[NEWS] ", /* LOG_NEWS */
99 "[UUCP] ", /* LOG_UUCP */
100 "[DAEMON] ", /* LOG_DAEMON */
101 "[AUTH] ", /* LOG_AUTH */
102 "[CRON] ", /* LOG_CRON */
103 "[LPR] ", /* LOG_LPR */
104 "[LOCAL0] ", /* LOG_LOCAL0 */
105 "[LOCAL1] ", /* LOG_LOCAL1 */
106 "[LOCAL2] ", /* LOG_LOCAL2 */
107 "[LOCAL3] ", /* LOG_LOCAL3 */
108 "[LOCAL4] ", /* LOG_LOCAL4 */
109 "[LOCAL5] ", /* LOG_LOCAL5 */
110 "[LOCAL6] ", /* LOG_LOCAL6 */
111 "[LOCAL7] "}; /* LOG_LOCAL7 */
112
113/* syslog functions */
114
115static void open_syslog (void)
116{
117 if (vos_syslog_fd >= 0)
118 return;
119
120 vos_syslog_fd = open (vos_syslog_path, O_RDWR | O_CREAT | O_APPEND, 0777);
121 if (vos_syslog_fd < 0)
122 fprintf (stderr, "Unable to open %s (errno=%d, os_errno=%d)\n",
123 vos_syslog_path, errno, os_errno);
124}
125
126void closelog (void)
127{
128 if (vos_syslog_fd >= 0)
129 close (vos_syslog_fd);
130
131 vos_syslog_facility = LOG_USER>>3;
132 vos_syslog_fd = -1;
133 vos_syslog_logopt = 0;
134 vos_syslog_ident[0] = '\0';
135 vos_syslog_ident_len = 0;
136 vos_syslog_mask = ALL_PRIORITIES;
137 return;
138}
139
140void openlog (const char *ident, int logopt, int facility)
141{
142int n;
143
144 if (ident != NULL)
145 {
146 strncpy (vos_syslog_ident, ident, sizeof (vos_syslog_ident));
147 n = IDENT_LEN -
148 strnlen (vos_syslog_ident, sizeof (vos_syslog_ident));
149 strncat (vos_syslog_ident, ": ", n);
150 vos_syslog_ident_len = strnlen (vos_syslog_ident,
151 sizeof (vos_syslog_ident));
152 }
153
154 vos_syslog_logopt = logopt;
155 vos_syslog_facility = facility>>3;
156
157 if ((logopt & LOG_NDELAY) == LOG_NDELAY)
158 open_syslog ();
159
160 return;
161}
162
163int setlogmask (int maskpri)
164{
165int old_mask;
166
167 old_mask = vos_syslog_mask;
168
169 if (maskpri > 0)
170 vos_syslog_mask = maskpri;
171
172 return old_mask;
173}
174
175void syslog (int priority, const char *format, ...)
176{
177va_list ap;
178int bare_facility;
179int bare_priority;
180int buffer_n;
181char buffer[BUFFER_LEN];
182short int code;
183char_varying(MSG_LEN) message;
184char_varying(66) module_name;
185int n;
186int pid_n;
187char pid_string[32];
188int r;
189int user_n;
190char user_string[256];
191
192 /* Calculate priority and facility value. */
193
194 bare_priority = priority & 3;
195 bare_facility = priority >> 3;
196
197 /* If the priority is not set in the mask, do not log the
198 message. */
199
200 if ((vos_syslog_mask & LOG_MASK(bare_priority)) == 0)
201 return;
202
203 /* Output facility name. */
204
205 if (bare_facility == 0)
206 bare_facility = vos_syslog_facility;
207
208 strcpy (buffer, vos_syslog_facility_name[bare_facility]);
209
210 /* Output priority value. */
211
212 /* TBD */
213
214 /* Output identity string. */
215
216 buffer_n = BUFFER_LEN - strlen (buffer);
217 strncat (buffer, vos_syslog_ident, buffer_n);
218
219 /* Output process ID. */
220
221 if ((vos_syslog_logopt & LOG_PID) == LOG_PID)
222 {
223 pid_n = snprintf (pid_string, sizeof (pid_string),
224 "PID=0x%x ", getpid ());
225 if (pid_n)
226 {
227 buffer_n = BUFFER_LEN - strlen (buffer);
228 strncat (buffer, pid_string, buffer_n);
229 }
230 }
231
232 /* Output formatted message. */
233
234 va_start (ap, format);
235 user_n = vsnprintf (user_string, sizeof (user_string), format, ap);
236 va_end (ap);
237
238 /* Ensure string ends in a newline. */
239
240 if (user_n > 0)
241 {
242 if (user_n >= sizeof (user_string))
243 user_n = sizeof (user_string) - 1;
244
245 /* arrays are zero-origin.... */
246
247 if (user_string [user_n-1] != '\n')
248 {
249 user_string [user_n-1] = '\n';
250 user_string [user_n++] = '\0';
251 }
252 }
253 else
254 {
255 user_string [0] = '\n';
256 user_string [1] = '\0';
257 user_n = 1;
258 }
259
260 buffer_n = BUFFER_LEN - strnlen (buffer, sizeof (buffer));
261 strncat (buffer, user_string, buffer_n);
262
263 /* If the log is not open, try to open it now. */
264
265 if (vos_syslog_fd < 0)
266 open_syslog ();
267
268 /* Try to write the message to the syslog file. */
269
270 if (vos_syslog_fd < 0)
271 r = -1;
272 else
273 {
274 buffer_n = strnlen (buffer, sizeof (buffer));
275 r = write (vos_syslog_fd, buffer, buffer_n);
276 }
277
278 /* If we were unable to write to the log and if LOG_CONS is
279 set, send it to the console. */
280
281 if (r < 0)
282 if ((vos_syslog_logopt & LOG_CONS) == LOG_CONS)
283 {
284 strcpy_vstr_nstr (&message, "syslog: ");
285 n = MSG_LEN - sizeof ("syslog: ");
286 strncat_vstr_nstr (&message, buffer, n);
287 strcpy_vstr_nstr (&module_name, "");
288 s$log_system_message (&message, &module_name, &code);
289 }
290
291 return;
292}