This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Yitzchak points out that the perldiag entry for "Integer overflow in
[perl5.git] / util.c
CommitLineData
a0d0e21e 1/* util.c
a687059c 2 *
4bb101f2 3 * Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999,
b94e2f88 4 * 2000, 2001, 2002, 2003, 2004, 2005, 2006, by Larry Wall and others
a687059c 5 *
d48672a2
LW
6 * You may distribute under the terms of either the GNU General Public
7 * License or the Artistic License, as specified in the README file.
8d063cd8 8 *
8d063cd8 9 */
a0d0e21e
LW
10
11/*
12 * "Very useful, no doubt, that was to Saruman; yet it seems that he was
13 * not content." --Gandalf
14 */
8d063cd8 15
166f8a29
DM
16/* This file contains assorted utility routines.
17 * Which is a polite way of saying any stuff that people couldn't think of
18 * a better place for. Amongst other things, it includes the warning and
19 * dieing stuff, plus wrappers for malloc code.
20 */
21
8d063cd8 22#include "EXTERN.h"
864dbfa3 23#define PERL_IN_UTIL_C
8d063cd8 24#include "perl.h"
62b28dd9 25
64ca3a65 26#ifndef PERL_MICRO
a687059c 27#include <signal.h>
36477c24 28#ifndef SIG_ERR
29# define SIG_ERR ((Sighandler_t) -1)
30#endif
64ca3a65 31#endif
36477c24 32
172d2248
OS
33#ifdef __Lynx__
34/* Missing protos on LynxOS */
35int putenv(char *);
36#endif
37
ff68c719 38#ifdef I_SYS_WAIT
39# include <sys/wait.h>
40#endif
41
868439a2
JH
42#ifdef HAS_SELECT
43# ifdef I_SYS_SELECT
44# include <sys/select.h>
45# endif
46#endif
47
8d063cd8 48#define FLUSH
8d063cd8 49
16cebae2
GS
50#if defined(HAS_FCNTL) && defined(F_SETFD) && !defined(FD_CLOEXEC)
51# define FD_CLOEXEC 1 /* NeXT needs this */
52#endif
53
a687059c
LW
54/* NOTE: Do not call the next three routines directly. Use the macros
55 * in handy.h, so that we can easily redefine everything to do tracking of
56 * allocated hunks back to the original New to track down any memory leaks.
20cec16a 57 * XXX This advice seems to be widely ignored :-( --AD August 1996.
a687059c
LW
58 */
59
ca8d8976
NC
60static char *
61S_write_no_mem(pTHX)
62{
97aff369 63 dVAR;
ca8d8976
NC
64 /* Can't use PerlIO to write as it allocates memory */
65 PerlLIO_write(PerlIO_fileno(Perl_error_log),
66 PL_no_mem, strlen(PL_no_mem));
67 my_exit(1);
1f440eb2 68 NORETURN_FUNCTION_END;
ca8d8976
NC
69}
70
26fa51c3
AMS
71/* paranoid version of system's malloc() */
72
bd4080b3 73Malloc_t
4f63d024 74Perl_safesysmalloc(MEM_SIZE size)
8d063cd8 75{
54aff467 76 dTHX;
bd4080b3 77 Malloc_t ptr;
55497cff 78#ifdef HAS_64K_LIMIT
62b28dd9 79 if (size > 0xffff) {
bf49b057 80 PerlIO_printf(Perl_error_log,
16cebae2 81 "Allocation too large: %lx\n", size) FLUSH;
54aff467 82 my_exit(1);
62b28dd9 83 }
55497cff 84#endif /* HAS_64K_LIMIT */
e8dda941
JD
85#ifdef PERL_TRACK_MEMPOOL
86 size += sTHX;
87#endif
34de22dd
LW
88#ifdef DEBUGGING
89 if ((long)size < 0)
4f63d024 90 Perl_croak_nocontext("panic: malloc");
34de22dd 91#endif
12ae5dfc 92 ptr = (Malloc_t)PerlMem_malloc(size?size:1); /* malloc(0) is NASTY on our system */
da927450 93 PERL_ALLOC_CHECK(ptr);
97835f67 94 DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%"UVxf": (%05ld) malloc %ld bytes\n",PTR2UV(ptr),(long)PL_an++,(long)size));
bd61b366 95 if (ptr != NULL) {
e8dda941 96#ifdef PERL_TRACK_MEMPOOL
7cb608b5
NC
97 struct perl_memory_debug_header *const header
98 = (struct perl_memory_debug_header *)ptr;
9a083ecf
NC
99#endif
100
101#ifdef PERL_POISON
102 Poison(((char *)ptr), size, char);
103#endif
7cb608b5 104
9a083ecf 105#ifdef PERL_TRACK_MEMPOOL
7cb608b5
NC
106 header->interpreter = aTHX;
107 /* Link us into the list. */
108 header->prev = &PL_memory_debug_header;
109 header->next = PL_memory_debug_header.next;
110 PL_memory_debug_header.next = header;
111 header->next->prev = header;
cd1541b2 112# ifdef PERL_POISON
7cb608b5 113 header->size = size;
cd1541b2 114# endif
e8dda941
JD
115 ptr = (Malloc_t)((char*)ptr+sTHX);
116#endif
8d063cd8 117 return ptr;
e8dda941 118}
3280af22 119 else if (PL_nomemok)
bd61b366 120 return NULL;
8d063cd8 121 else {
0bd48802 122 return write_no_mem();
8d063cd8
LW
123 }
124 /*NOTREACHED*/
125}
126
f2517201 127/* paranoid version of system's realloc() */
8d063cd8 128
bd4080b3 129Malloc_t
4f63d024 130Perl_safesysrealloc(Malloc_t where,MEM_SIZE size)
8d063cd8 131{
54aff467 132 dTHX;
bd4080b3 133 Malloc_t ptr;
9a34ef1d 134#if !defined(STANDARD_C) && !defined(HAS_REALLOC_PROTOTYPE) && !defined(PERL_MICRO)
6ad3d225 135 Malloc_t PerlMem_realloc();
ecfc5424 136#endif /* !defined(STANDARD_C) && !defined(HAS_REALLOC_PROTOTYPE) */
8d063cd8 137
a1d180c4 138#ifdef HAS_64K_LIMIT
5f05dabc 139 if (size > 0xffff) {
bf49b057 140 PerlIO_printf(Perl_error_log,
5f05dabc 141 "Reallocation too large: %lx\n", size) FLUSH;
54aff467 142 my_exit(1);
5f05dabc 143 }
55497cff 144#endif /* HAS_64K_LIMIT */
7614df0c 145 if (!size) {
f2517201 146 safesysfree(where);
7614df0c
JD
147 return NULL;
148 }
149
378cc40b 150 if (!where)
f2517201 151 return safesysmalloc(size);
e8dda941
JD
152#ifdef PERL_TRACK_MEMPOOL
153 where = (Malloc_t)((char*)where-sTHX);
154 size += sTHX;
7cb608b5
NC
155 {
156 struct perl_memory_debug_header *const header
157 = (struct perl_memory_debug_header *)where;
158
159 if (header->interpreter != aTHX) {
160 Perl_croak_nocontext("panic: realloc from wrong pool");
161 }
162 assert(header->next->prev == header);
163 assert(header->prev->next == header);
cd1541b2 164# ifdef PERL_POISON
7cb608b5
NC
165 if (header->size > size) {
166 const MEM_SIZE freed_up = header->size - size;
167 char *start_of_freed = ((char *)where) + size;
168 Poison(start_of_freed, freed_up, char);
169 }
170 header->size = size;
cd1541b2 171# endif
7cb608b5 172 }
e8dda941 173#endif
34de22dd
LW
174#ifdef DEBUGGING
175 if ((long)size < 0)
4f63d024 176 Perl_croak_nocontext("panic: realloc");
34de22dd 177#endif
12ae5dfc 178 ptr = (Malloc_t)PerlMem_realloc(where,size);
da927450 179 PERL_ALLOC_CHECK(ptr);
a1d180c4 180
97835f67
JH
181 DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%"UVxf": (%05ld) rfree\n",PTR2UV(where),(long)PL_an++));
182 DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%"UVxf": (%05ld) realloc %ld bytes\n",PTR2UV(ptr),(long)PL_an++,(long)size));
79072805 183
bd61b366 184 if (ptr != NULL) {
e8dda941 185#ifdef PERL_TRACK_MEMPOOL
7cb608b5
NC
186 struct perl_memory_debug_header *const header
187 = (struct perl_memory_debug_header *)ptr;
188
9a083ecf
NC
189# ifdef PERL_POISON
190 if (header->size < size) {
191 const MEM_SIZE fresh = size - header->size;
192 char *start_of_fresh = ((char *)ptr) + size;
193 Poison(start_of_fresh, fresh, char);
194 }
195# endif
196
7cb608b5
NC
197 header->next->prev = header;
198 header->prev->next = header;
199
e8dda941
JD
200 ptr = (Malloc_t)((char*)ptr+sTHX);
201#endif
8d063cd8 202 return ptr;
e8dda941 203 }
3280af22 204 else if (PL_nomemok)
bd61b366 205 return NULL;
8d063cd8 206 else {
0bd48802 207 return write_no_mem();
8d063cd8
LW
208 }
209 /*NOTREACHED*/
210}
211
f2517201 212/* safe version of system's free() */
8d063cd8 213
54310121 214Free_t
4f63d024 215Perl_safesysfree(Malloc_t where)
8d063cd8 216{
e8dda941 217#if defined(PERL_IMPLICIT_SYS) || defined(PERL_TRACK_MEMPOOL)
54aff467 218 dTHX;
97aff369
JH
219#else
220 dVAR;
155aba94 221#endif
97835f67 222 DEBUG_m( PerlIO_printf(Perl_debug_log, "0x%"UVxf": (%05ld) free\n",PTR2UV(where),(long)PL_an++));
378cc40b 223 if (where) {
e8dda941
JD
224#ifdef PERL_TRACK_MEMPOOL
225 where = (Malloc_t)((char*)where-sTHX);
cd1541b2 226 {
7cb608b5
NC
227 struct perl_memory_debug_header *const header
228 = (struct perl_memory_debug_header *)where;
229
230 if (header->interpreter != aTHX) {
231 Perl_croak_nocontext("panic: free from wrong pool");
232 }
233 if (!header->prev) {
cd1541b2
NC
234 Perl_croak_nocontext("panic: duplicate free");
235 }
7cb608b5
NC
236 if (!(header->next) || header->next->prev != header
237 || header->prev->next != header) {
238 Perl_croak_nocontext("panic: bad free");
cd1541b2 239 }
7cb608b5
NC
240 /* Unlink us from the chain. */
241 header->next->prev = header->prev;
242 header->prev->next = header->next;
243# ifdef PERL_POISON
244 Poison(where, header->size, char);
cd1541b2 245# endif
7cb608b5
NC
246 /* Trigger the duplicate free warning. */
247 header->next = NULL;
248 }
e8dda941 249#endif
6ad3d225 250 PerlMem_free(where);
378cc40b 251 }
8d063cd8
LW
252}
253
f2517201 254/* safe version of system's calloc() */
1050c9ca 255
bd4080b3 256Malloc_t
4f63d024 257Perl_safesyscalloc(MEM_SIZE count, MEM_SIZE size)
1050c9ca 258{
54aff467 259 dTHX;
bd4080b3 260 Malloc_t ptr;
1050c9ca 261
55497cff 262#ifdef HAS_64K_LIMIT
5f05dabc 263 if (size * count > 0xffff) {
bf49b057 264 PerlIO_printf(Perl_error_log,
5f05dabc 265 "Allocation too large: %lx\n", size * count) FLUSH;
54aff467 266 my_exit(1);
5f05dabc 267 }
55497cff 268#endif /* HAS_64K_LIMIT */
1050c9ca 269#ifdef DEBUGGING
270 if ((long)size < 0 || (long)count < 0)
4f63d024 271 Perl_croak_nocontext("panic: calloc");
1050c9ca 272#endif
0b7c1c42 273 size *= count;
e8dda941
JD
274#ifdef PERL_TRACK_MEMPOOL
275 size += sTHX;
276#endif
12ae5dfc 277 ptr = (Malloc_t)PerlMem_malloc(size?size:1); /* malloc(0) is NASTY on our system */
da927450 278 PERL_ALLOC_CHECK(ptr);
97835f67 279 DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%"UVxf": (%05ld) calloc %ld x %ld bytes\n",PTR2UV(ptr),(long)PL_an++,(long)count,(long)size));
bd61b366 280 if (ptr != NULL) {
1050c9ca 281 memset((void*)ptr, 0, size);
e8dda941 282#ifdef PERL_TRACK_MEMPOOL
7cb608b5
NC
283 {
284 struct perl_memory_debug_header *const header
285 = (struct perl_memory_debug_header *)ptr;
286
287 header->interpreter = aTHX;
288 /* Link us into the list. */
289 header->prev = &PL_memory_debug_header;
290 header->next = PL_memory_debug_header.next;
291 PL_memory_debug_header.next = header;
292 header->next->prev = header;
cd1541b2 293# ifdef PERL_POISON
7cb608b5 294 header->size = size;
cd1541b2 295# endif
7cb608b5
NC
296 ptr = (Malloc_t)((char*)ptr+sTHX);
297 }
e8dda941 298#endif
1050c9ca 299 return ptr;
300 }
3280af22 301 else if (PL_nomemok)
bd61b366 302 return NULL;
0bd48802 303 return write_no_mem();
1050c9ca 304}
305
cae6d0e5
GS
306/* These must be defined when not using Perl's malloc for binary
307 * compatibility */
308
309#ifndef MYMALLOC
310
311Malloc_t Perl_malloc (MEM_SIZE nbytes)
312{
313 dTHXs;
077a72a9 314 return (Malloc_t)PerlMem_malloc(nbytes);
cae6d0e5
GS
315}
316
317Malloc_t Perl_calloc (MEM_SIZE elements, MEM_SIZE size)
318{
319 dTHXs;
077a72a9 320 return (Malloc_t)PerlMem_calloc(elements, size);
cae6d0e5
GS
321}
322
323Malloc_t Perl_realloc (Malloc_t where, MEM_SIZE nbytes)
324{
325 dTHXs;
077a72a9 326 return (Malloc_t)PerlMem_realloc(where, nbytes);
cae6d0e5
GS
327}
328
329Free_t Perl_mfree (Malloc_t where)
330{
331 dTHXs;
332 PerlMem_free(where);
333}
334
335#endif
336
8d063cd8
LW
337/* copy a string up to some (non-backslashed) delimiter, if any */
338
339char *
e1ec3a88 340Perl_delimcpy(pTHX_ register char *to, register const char *toend, register const char *from, register const char *fromend, register int delim, I32 *retlen)
8d063cd8 341{
fc36a67e 342 register I32 tolen;
343 for (tolen = 0; from < fromend; from++, tolen++) {
378cc40b
LW
344 if (*from == '\\') {
345 if (from[1] == delim)
346 from++;
fc36a67e 347 else {
348 if (to < toend)
349 *to++ = *from;
350 tolen++;
351 from++;
352 }
378cc40b 353 }
bedebaa5 354 else if (*from == delim)
8d063cd8 355 break;
fc36a67e 356 if (to < toend)
357 *to++ = *from;
8d063cd8 358 }
bedebaa5
CS
359 if (to < toend)
360 *to = '\0';
fc36a67e 361 *retlen = tolen;
73d840c0 362 return (char *)from;
8d063cd8
LW
363}
364
365/* return ptr to little string in big string, NULL if not found */
378cc40b 366/* This routine was donated by Corey Satten. */
8d063cd8
LW
367
368char *
864dbfa3 369Perl_instr(pTHX_ register const char *big, register const char *little)
378cc40b 370{
79072805 371 register I32 first;
378cc40b 372
a687059c 373 if (!little)
08105a92 374 return (char*)big;
a687059c 375 first = *little++;
378cc40b 376 if (!first)
08105a92 377 return (char*)big;
378cc40b 378 while (*big) {
66a1b24b 379 register const char *s, *x;
378cc40b
LW
380 if (*big++ != first)
381 continue;
382 for (x=big,s=little; *s; /**/ ) {
383 if (!*x)
bd61b366 384 return NULL;
4fc877ac 385 if (*s != *x)
378cc40b 386 break;
4fc877ac
AL
387 else {
388 s++;
389 x++;
378cc40b
LW
390 }
391 }
392 if (!*s)
08105a92 393 return (char*)(big-1);
378cc40b 394 }
bd61b366 395 return NULL;
378cc40b 396}
8d063cd8 397
a687059c
LW
398/* same as instr but allow embedded nulls */
399
400char *
4c8626be 401Perl_ninstr(pTHX_ const char *big, const char *bigend, const char *little, const char *lend)
8d063cd8 402{
4c8626be
GA
403 if (little >= lend)
404 return (char*)big;
405 {
406 char first = *little++;
407 const char *s, *x;
408 bigend -= lend - little;
409 OUTER:
410 while (big <= bigend) {
411 if (*big++ != first)
412 goto OUTER;
413 for (x=big,s=little; s < lend; x++,s++) {
414 if (*s != *x)
415 goto OUTER;
416 }
417 return (char*)(big-1);
418 }
378cc40b 419 }
bd61b366 420 return NULL;
a687059c
LW
421}
422
423/* reverse of the above--find last substring */
424
425char *
864dbfa3 426Perl_rninstr(pTHX_ register const char *big, const char *bigend, const char *little, const char *lend)
a687059c 427{
08105a92 428 register const char *bigbeg;
e1ec3a88 429 register const I32 first = *little;
7452cf6a 430 register const char * const littleend = lend;
a687059c 431
260d78c9 432 if (little >= littleend)
08105a92 433 return (char*)bigend;
a687059c
LW
434 bigbeg = big;
435 big = bigend - (littleend - little++);
436 while (big >= bigbeg) {
66a1b24b 437 register const char *s, *x;
a687059c
LW
438 if (*big-- != first)
439 continue;
440 for (x=big+2,s=little; s < littleend; /**/ ) {
4fc877ac 441 if (*s != *x)
a687059c 442 break;
4fc877ac
AL
443 else {
444 x++;
445 s++;
a687059c
LW
446 }
447 }
448 if (s >= littleend)
08105a92 449 return (char*)(big+1);
378cc40b 450 }
bd61b366 451 return NULL;
378cc40b 452}
a687059c 453
cf93c79d
IZ
454#define FBM_TABLE_OFFSET 2 /* Number of bytes between EOS and table*/
455
456/* As a space optimization, we do not compile tables for strings of length
457 0 and 1, and for strings of length 2 unless FBMcf_TAIL. These are
458 special-cased in fbm_instr().
459
460 If FBMcf_TAIL, the table is created as if the string has a trailing \n. */
461
954c1994 462/*
ccfc67b7
JH
463=head1 Miscellaneous Functions
464
954c1994
GS
465=for apidoc fbm_compile
466
467Analyses the string in order to make fast searches on it using fbm_instr()
468-- the Boyer-Moore algorithm.
469
470=cut
471*/
472
378cc40b 473void
7506f9c3 474Perl_fbm_compile(pTHX_ SV *sv, U32 flags)
378cc40b 475{
97aff369 476 dVAR;
0d46e09a 477 register const U8 *s;
79072805 478 register U32 i;
0b71040e 479 STRLEN len;
79072805
LW
480 I32 rarest = 0;
481 U32 frequency = 256;
482
c517dc2b 483 if (flags & FBMcf_TAIL) {
890ce7af 484 MAGIC * const mg = SvUTF8(sv) && SvMAGICAL(sv) ? mg_find(sv, PERL_MAGIC_utf8) : NULL;
396482e1 485 sv_catpvs(sv, "\n"); /* Taken into account in fbm_instr() */
c517dc2b
JH
486 if (mg && mg->mg_len >= 0)
487 mg->mg_len++;
488 }
9cbe880b 489 s = (U8*)SvPV_force_mutable(sv, len);
862a34c6 490 SvUPGRADE(sv, SVt_PVBM);
d1be9408 491 if (len == 0) /* TAIL might be on a zero-length string. */
cf93c79d 492 return;
02128f11 493 if (len > 2) {
9cbe880b 494 const unsigned char *sb;
66a1b24b 495 const U8 mlen = (len>255) ? 255 : (U8)len;
890ce7af 496 register U8 *table;
cf93c79d 497
7506f9c3 498 Sv_Grow(sv, len + 256 + FBM_TABLE_OFFSET);
9cbe880b 499 table = (unsigned char*)(SvPVX_mutable(sv) + len + FBM_TABLE_OFFSET);
7506f9c3
GS
500 s = table - 1 - FBM_TABLE_OFFSET; /* last char */
501 memset((void*)table, mlen, 256);
502 table[-1] = (U8)flags;
02128f11 503 i = 0;
7506f9c3 504 sb = s - mlen + 1; /* first char (maybe) */
cf93c79d
IZ
505 while (s >= sb) {
506 if (table[*s] == mlen)
7506f9c3 507 table[*s] = (U8)i;
cf93c79d
IZ
508 s--, i++;
509 }
378cc40b 510 }
a0714e2c 511 sv_magic(sv, NULL, PERL_MAGIC_bm, NULL, 0); /* deep magic */
79072805 512 SvVALID_on(sv);
378cc40b 513
9cbe880b 514 s = (const unsigned char*)(SvPVX_const(sv)); /* deeper magic */
bbce6d69 515 for (i = 0; i < len; i++) {
22c35a8c 516 if (PL_freq[s[i]] < frequency) {
bbce6d69 517 rarest = i;
22c35a8c 518 frequency = PL_freq[s[i]];
378cc40b
LW
519 }
520 }
79072805 521 BmRARE(sv) = s[rarest];
eb160463 522 BmPREVIOUS(sv) = (U16)rarest;
cf93c79d
IZ
523 BmUSEFUL(sv) = 100; /* Initial value */
524 if (flags & FBMcf_TAIL)
525 SvTAIL_on(sv);
7506f9c3
GS
526 DEBUG_r(PerlIO_printf(Perl_debug_log, "rarest char %c at %d\n",
527 BmRARE(sv),BmPREVIOUS(sv)));
378cc40b
LW
528}
529
cf93c79d
IZ
530/* If SvTAIL(littlestr), it has a fake '\n' at end. */
531/* If SvTAIL is actually due to \Z or \z, this gives false positives
532 if multiline */
533
954c1994
GS
534/*
535=for apidoc fbm_instr
536
537Returns the location of the SV in the string delimited by C<str> and
bd61b366 538C<strend>. It returns C<NULL> if the string can't be found. The C<sv>
954c1994
GS
539does not have to be fbm_compiled, but the search will not be as fast
540then.
541
542=cut
543*/
544
378cc40b 545char *
864dbfa3 546Perl_fbm_instr(pTHX_ unsigned char *big, register unsigned char *bigend, SV *littlestr, U32 flags)
378cc40b 547{
a687059c 548 register unsigned char *s;
cf93c79d 549 STRLEN l;
9cbe880b
NC
550 register const unsigned char *little
551 = (const unsigned char *)SvPV_const(littlestr,l);
cf93c79d 552 register STRLEN littlelen = l;
e1ec3a88 553 register const I32 multiline = flags & FBMrf_MULTILINE;
cf93c79d 554
eb160463 555 if ((STRLEN)(bigend - big) < littlelen) {
a1d180c4 556 if ( SvTAIL(littlestr)
eb160463 557 && ((STRLEN)(bigend - big) == littlelen - 1)
a1d180c4 558 && (littlelen == 1
12ae5dfc 559 || (*big == *little &&
27da23d5 560 memEQ((char *)big, (char *)little, littlelen - 1))))
cf93c79d 561 return (char*)big;
bd61b366 562 return NULL;
cf93c79d 563 }
378cc40b 564
cf93c79d 565 if (littlelen <= 2) { /* Special-cased */
cf93c79d
IZ
566
567 if (littlelen == 1) {
568 if (SvTAIL(littlestr) && !multiline) { /* Anchor only! */
569 /* Know that bigend != big. */
570 if (bigend[-1] == '\n')
571 return (char *)(bigend - 1);
572 return (char *) bigend;
573 }
574 s = big;
575 while (s < bigend) {
576 if (*s == *little)
577 return (char *)s;
578 s++;
579 }
580 if (SvTAIL(littlestr))
581 return (char *) bigend;
bd61b366 582 return NULL;
cf93c79d
IZ
583 }
584 if (!littlelen)
585 return (char*)big; /* Cannot be SvTAIL! */
586
587 /* littlelen is 2 */
588 if (SvTAIL(littlestr) && !multiline) {
589 if (bigend[-1] == '\n' && bigend[-2] == *little)
590 return (char*)bigend - 2;
591 if (bigend[-1] == *little)
592 return (char*)bigend - 1;
bd61b366 593 return NULL;
cf93c79d
IZ
594 }
595 {
596 /* This should be better than FBM if c1 == c2, and almost
597 as good otherwise: maybe better since we do less indirection.
598 And we save a lot of memory by caching no table. */
66a1b24b
AL
599 const unsigned char c1 = little[0];
600 const unsigned char c2 = little[1];
cf93c79d
IZ
601
602 s = big + 1;
603 bigend--;
604 if (c1 != c2) {
605 while (s <= bigend) {
606 if (s[0] == c2) {
607 if (s[-1] == c1)
608 return (char*)s - 1;
609 s += 2;
610 continue;
3fe6f2dc 611 }
cf93c79d
IZ
612 next_chars:
613 if (s[0] == c1) {
614 if (s == bigend)
615 goto check_1char_anchor;
616 if (s[1] == c2)
617 return (char*)s;
618 else {
619 s++;
620 goto next_chars;
621 }
622 }
623 else
624 s += 2;
625 }
626 goto check_1char_anchor;
627 }
628 /* Now c1 == c2 */
629 while (s <= bigend) {
630 if (s[0] == c1) {
631 if (s[-1] == c1)
632 return (char*)s - 1;
633 if (s == bigend)
634 goto check_1char_anchor;
635 if (s[1] == c1)
636 return (char*)s;
637 s += 3;
02128f11 638 }
c277df42 639 else
cf93c79d 640 s += 2;
c277df42 641 }
c277df42 642 }
cf93c79d
IZ
643 check_1char_anchor: /* One char and anchor! */
644 if (SvTAIL(littlestr) && (*bigend == *little))
645 return (char *)bigend; /* bigend is already decremented. */
bd61b366 646 return NULL;
d48672a2 647 }
cf93c79d 648 if (SvTAIL(littlestr) && !multiline) { /* tail anchored? */
bbce6d69 649 s = bigend - littlelen;
a1d180c4 650 if (s >= big && bigend[-1] == '\n' && *s == *little
cf93c79d
IZ
651 /* Automatically of length > 2 */
652 && memEQ((char*)s + 1, (char*)little + 1, littlelen - 2))
7506f9c3 653 {
bbce6d69 654 return (char*)s; /* how sweet it is */
7506f9c3
GS
655 }
656 if (s[1] == *little
657 && memEQ((char*)s + 2, (char*)little + 1, littlelen - 2))
658 {
cf93c79d 659 return (char*)s + 1; /* how sweet it is */
7506f9c3 660 }
bd61b366 661 return NULL;
02128f11 662 }
cf93c79d 663 if (SvTYPE(littlestr) != SVt_PVBM || !SvVALID(littlestr)) {
c4420975 664 char * const b = ninstr((char*)big,(char*)bigend,
cf93c79d
IZ
665 (char*)little, (char*)little + littlelen);
666
667 if (!b && SvTAIL(littlestr)) { /* Automatically multiline! */
668 /* Chop \n from littlestr: */
669 s = bigend - littlelen + 1;
7506f9c3
GS
670 if (*s == *little
671 && memEQ((char*)s + 1, (char*)little + 1, littlelen - 2))
672 {
3fe6f2dc 673 return (char*)s;
7506f9c3 674 }
bd61b366 675 return NULL;
a687059c 676 }
cf93c79d 677 return b;
a687059c 678 }
a1d180c4 679
cf93c79d 680 { /* Do actual FBM. */
c4420975 681 register const unsigned char * const table = little + littlelen + FBM_TABLE_OFFSET;
0d46e09a 682 register const unsigned char *oldlittle;
cf93c79d 683
eb160463 684 if (littlelen > (STRLEN)(bigend - big))
bd61b366 685 return NULL;
cf93c79d
IZ
686 --littlelen; /* Last char found by table lookup */
687
688 s = big + littlelen;
689 little += littlelen; /* last char */
690 oldlittle = little;
691 if (s < bigend) {
692 register I32 tmp;
693
694 top2:
7506f9c3 695 if ((tmp = table[*s])) {
cf93c79d 696 if ((s += tmp) < bigend)
62b28dd9 697 goto top2;
cf93c79d
IZ
698 goto check_end;
699 }
700 else { /* less expensive than calling strncmp() */
66a1b24b 701 register unsigned char * const olds = s;
cf93c79d
IZ
702
703 tmp = littlelen;
704
705 while (tmp--) {
706 if (*--s == *--little)
707 continue;
cf93c79d
IZ
708 s = olds + 1; /* here we pay the price for failure */
709 little = oldlittle;
710 if (s < bigend) /* fake up continue to outer loop */
711 goto top2;
712 goto check_end;
713 }
714 return (char *)s;
a687059c 715 }
378cc40b 716 }
cf93c79d
IZ
717 check_end:
718 if ( s == bigend && (table[-1] & FBMcf_TAIL)
12ae5dfc
JH
719 && memEQ((char *)(bigend - littlelen),
720 (char *)(oldlittle - littlelen), littlelen) )
cf93c79d 721 return (char*)bigend - littlelen;
bd61b366 722 return NULL;
378cc40b 723 }
378cc40b
LW
724}
725
c277df42
IZ
726/* start_shift, end_shift are positive quantities which give offsets
727 of ends of some substring of bigstr.
a0288114 728 If "last" we want the last occurrence.
c277df42 729 old_posp is the way of communication between consequent calls if
a1d180c4 730 the next call needs to find the .
c277df42 731 The initial *old_posp should be -1.
cf93c79d
IZ
732
733 Note that we take into account SvTAIL, so one can get extra
734 optimizations if _ALL flag is set.
c277df42
IZ
735 */
736
cf93c79d 737/* If SvTAIL is actually due to \Z or \z, this gives false positives
26fa51c3 738 if PL_multiline. In fact if !PL_multiline the authoritative answer
cf93c79d
IZ
739 is not supported yet. */
740
378cc40b 741char *
864dbfa3 742Perl_screaminstr(pTHX_ SV *bigstr, SV *littlestr, I32 start_shift, I32 end_shift, I32 *old_posp, I32 last)
378cc40b 743{
97aff369 744 dVAR;
0d46e09a 745 register const unsigned char *big;
79072805
LW
746 register I32 pos;
747 register I32 previous;
748 register I32 first;
0d46e09a 749 register const unsigned char *little;
c277df42 750 register I32 stop_pos;
0d46e09a 751 register const unsigned char *littleend;
c277df42 752 I32 found = 0;
378cc40b 753
c277df42 754 if (*old_posp == -1
3280af22 755 ? (pos = PL_screamfirst[BmRARE(littlestr)]) < 0
cf93c79d
IZ
756 : (((pos = *old_posp), pos += PL_screamnext[pos]) == 0)) {
757 cant_find:
a1d180c4 758 if ( BmRARE(littlestr) == '\n'
cf93c79d 759 && BmPREVIOUS(littlestr) == SvCUR(littlestr) - 1) {
cfd0369c 760 little = (const unsigned char *)(SvPVX_const(littlestr));
cf93c79d
IZ
761 littleend = little + SvCUR(littlestr);
762 first = *little++;
763 goto check_tail;
764 }
bd61b366 765 return NULL;
cf93c79d
IZ
766 }
767
cfd0369c 768 little = (const unsigned char *)(SvPVX_const(littlestr));
79072805 769 littleend = little + SvCUR(littlestr);
378cc40b 770 first = *little++;
c277df42 771 /* The value of pos we can start at: */
79072805 772 previous = BmPREVIOUS(littlestr);
cfd0369c 773 big = (const unsigned char *)(SvPVX_const(bigstr));
c277df42
IZ
774 /* The value of pos we can stop at: */
775 stop_pos = SvCUR(bigstr) - end_shift - (SvCUR(littlestr) - 1 - previous);
cf93c79d 776 if (previous + start_shift > stop_pos) {
0fe87f7c
HS
777/*
778 stop_pos does not include SvTAIL in the count, so this check is incorrect
779 (I think) - see [ID 20010618.006] and t/op/study.t. HVDS 2001/06/19
780*/
781#if 0
cf93c79d
IZ
782 if (previous + start_shift == stop_pos + 1) /* A fake '\n'? */
783 goto check_tail;
0fe87f7c 784#endif
bd61b366 785 return NULL;
cf93c79d 786 }
c277df42 787 while (pos < previous + start_shift) {
3280af22 788 if (!(pos += PL_screamnext[pos]))
cf93c79d 789 goto cant_find;
378cc40b 790 }
de3bb511 791 big -= previous;
bbce6d69 792 do {
0d46e09a 793 register const unsigned char *s, *x;
ef64f398 794 if (pos >= stop_pos) break;
bbce6d69 795 if (big[pos] != first)
796 continue;
797 for (x=big+pos+1,s=little; s < littleend; /**/ ) {
bbce6d69 798 if (*s++ != *x++) {
799 s--;
800 break;
378cc40b 801 }
bbce6d69 802 }
c277df42
IZ
803 if (s == littleend) {
804 *old_posp = pos;
805 if (!last) return (char *)(big+pos);
806 found = 1;
807 }
3280af22 808 } while ( pos += PL_screamnext[pos] );
a1d180c4 809 if (last && found)
cf93c79d 810 return (char *)(big+(*old_posp));
cf93c79d
IZ
811 check_tail:
812 if (!SvTAIL(littlestr) || (end_shift > 0))
bd61b366 813 return NULL;
cf93c79d 814 /* Ignore the trailing "\n". This code is not microoptimized */
cfd0369c 815 big = (const unsigned char *)(SvPVX_const(bigstr) + SvCUR(bigstr));
cf93c79d
IZ
816 stop_pos = littleend - little; /* Actual littlestr len */
817 if (stop_pos == 0)
818 return (char*)big;
819 big -= stop_pos;
820 if (*big == first
12ae5dfc
JH
821 && ((stop_pos == 1) ||
822 memEQ((char *)(big + 1), (char *)little, stop_pos - 1)))
cf93c79d 823 return (char*)big;
bd61b366 824 return NULL;
8d063cd8
LW
825}
826
79072805 827I32
864dbfa3 828Perl_ibcmp(pTHX_ const char *s1, const char *s2, register I32 len)
79072805 829{
e1ec3a88
AL
830 register const U8 *a = (const U8 *)s1;
831 register const U8 *b = (const U8 *)s2;
79072805 832 while (len--) {
22c35a8c 833 if (*a != *b && *a != PL_fold[*b])
bbce6d69 834 return 1;
835 a++,b++;
836 }
837 return 0;
838}
839
840I32
864dbfa3 841Perl_ibcmp_locale(pTHX_ const char *s1, const char *s2, register I32 len)
bbce6d69 842{
27da23d5 843 dVAR;
e1ec3a88
AL
844 register const U8 *a = (const U8 *)s1;
845 register const U8 *b = (const U8 *)s2;
bbce6d69 846 while (len--) {
22c35a8c 847 if (*a != *b && *a != PL_fold_locale[*b])
bbce6d69 848 return 1;
849 a++,b++;
79072805
LW
850 }
851 return 0;
852}
853
8d063cd8
LW
854/* copy a string to a safe spot */
855
954c1994 856/*
ccfc67b7
JH
857=head1 Memory Management
858
954c1994
GS
859=for apidoc savepv
860
61a925ed
AMS
861Perl's version of C<strdup()>. Returns a pointer to a newly allocated
862string which is a duplicate of C<pv>. The size of the string is
863determined by C<strlen()>. The memory allocated for the new string can
864be freed with the C<Safefree()> function.
954c1994
GS
865
866=cut
867*/
868
8d063cd8 869char *
efdfce31 870Perl_savepv(pTHX_ const char *pv)
8d063cd8 871{
e90e2364 872 if (!pv)
bd61b366 873 return NULL;
66a1b24b
AL
874 else {
875 char *newaddr;
876 const STRLEN pvlen = strlen(pv)+1;
a02a5408 877 Newx(newaddr,pvlen,char);
490a0e98 878 return memcpy(newaddr,pv,pvlen);
66a1b24b 879 }
e90e2364 880
8d063cd8
LW
881}
882
a687059c
LW
883/* same thing but with a known length */
884
954c1994
GS
885/*
886=for apidoc savepvn
887
61a925ed
AMS
888Perl's version of what C<strndup()> would be if it existed. Returns a
889pointer to a newly allocated string which is a duplicate of the first
890C<len> bytes from C<pv>. The memory allocated for the new string can be
891freed with the C<Safefree()> function.
954c1994
GS
892
893=cut
894*/
895
a687059c 896char *
efdfce31 897Perl_savepvn(pTHX_ const char *pv, register I32 len)
a687059c
LW
898{
899 register char *newaddr;
900
a02a5408 901 Newx(newaddr,len+1,char);
92110913 902 /* Give a meaning to NULL pointer mainly for the use in sv_magic() */
efdfce31 903 if (pv) {
e90e2364
NC
904 /* might not be null terminated */
905 newaddr[len] = '\0';
07409e01 906 return (char *) CopyD(pv,newaddr,len,char);
92110913
NIS
907 }
908 else {
07409e01 909 return (char *) ZeroD(newaddr,len+1,char);
92110913 910 }
a687059c
LW
911}
912
05ec9bb3
NIS
913/*
914=for apidoc savesharedpv
915
61a925ed
AMS
916A version of C<savepv()> which allocates the duplicate string in memory
917which is shared between threads.
05ec9bb3
NIS
918
919=cut
920*/
921char *
efdfce31 922Perl_savesharedpv(pTHX_ const char *pv)
05ec9bb3 923{
e90e2364 924 register char *newaddr;
490a0e98 925 STRLEN pvlen;
e90e2364 926 if (!pv)
bd61b366 927 return NULL;
e90e2364 928
490a0e98
NC
929 pvlen = strlen(pv)+1;
930 newaddr = (char*)PerlMemShared_malloc(pvlen);
e90e2364 931 if (!newaddr) {
0bd48802 932 return write_no_mem();
05ec9bb3 933 }
490a0e98 934 return memcpy(newaddr,pv,pvlen);
05ec9bb3
NIS
935}
936
2e0de35c
NC
937/*
938=for apidoc savesvpv
939
6832267f 940A version of C<savepv()>/C<savepvn()> which gets the string to duplicate from
2e0de35c
NC
941the passed in SV using C<SvPV()>
942
943=cut
944*/
945
946char *
947Perl_savesvpv(pTHX_ SV *sv)
948{
949 STRLEN len;
7452cf6a 950 const char * const pv = SvPV_const(sv, len);
2e0de35c
NC
951 register char *newaddr;
952
26866f99 953 ++len;
a02a5408 954 Newx(newaddr,len,char);
07409e01 955 return (char *) CopyD(pv,newaddr,len,char);
2e0de35c 956}
05ec9bb3
NIS
957
958
cea2e8a9 959/* the SV for Perl_form() and mess() is not kept in an arena */
fc36a67e 960
76e3520e 961STATIC SV *
cea2e8a9 962S_mess_alloc(pTHX)
fc36a67e 963{
97aff369 964 dVAR;
fc36a67e 965 SV *sv;
966 XPVMG *any;
967
e72dc28c 968 if (!PL_dirty)
396482e1 969 return sv_2mortal(newSVpvs(""));
e72dc28c 970
0372dbb6
GS
971 if (PL_mess_sv)
972 return PL_mess_sv;
973
fc36a67e 974 /* Create as PVMG now, to avoid any upgrading later */
a02a5408
JC
975 Newx(sv, 1, SV);
976 Newxz(any, 1, XPVMG);
fc36a67e 977 SvFLAGS(sv) = SVt_PVMG;
978 SvANY(sv) = (void*)any;
6136c704 979 SvPV_set(sv, NULL);
fc36a67e 980 SvREFCNT(sv) = 1 << 30; /* practically infinite */
e72dc28c 981 PL_mess_sv = sv;
fc36a67e 982 return sv;
983}
984
c5be433b 985#if defined(PERL_IMPLICIT_CONTEXT)
cea2e8a9
GS
986char *
987Perl_form_nocontext(const char* pat, ...)
988{
989 dTHX;
c5be433b 990 char *retval;
cea2e8a9
GS
991 va_list args;
992 va_start(args, pat);
c5be433b 993 retval = vform(pat, &args);
cea2e8a9 994 va_end(args);
c5be433b 995 return retval;
cea2e8a9 996}
c5be433b 997#endif /* PERL_IMPLICIT_CONTEXT */
cea2e8a9 998
7c9e965c 999/*
ccfc67b7 1000=head1 Miscellaneous Functions
7c9e965c
JP
1001=for apidoc form
1002
1003Takes a sprintf-style format pattern and conventional
1004(non-SV) arguments and returns the formatted string.
1005
1006 (char *) Perl_form(pTHX_ const char* pat, ...)
1007
1008can be used any place a string (char *) is required:
1009
1010 char * s = Perl_form("%d.%d",major,minor);
1011
1012Uses a single private buffer so if you want to format several strings you
1013must explicitly copy the earlier strings away (and free the copies when you
1014are done).
1015
1016=cut
1017*/
1018
8990e307 1019char *
864dbfa3 1020Perl_form(pTHX_ const char* pat, ...)
8990e307 1021{
c5be433b 1022 char *retval;
46fc3d4c 1023 va_list args;
46fc3d4c 1024 va_start(args, pat);
c5be433b 1025 retval = vform(pat, &args);
46fc3d4c 1026 va_end(args);
c5be433b
GS
1027 return retval;
1028}
1029
1030char *
1031Perl_vform(pTHX_ const char *pat, va_list *args)
1032{
2d03de9c 1033 SV * const sv = mess_alloc();
c5be433b 1034 sv_vsetpvfn(sv, pat, strlen(pat), args, Null(SV**), 0, Null(bool*));
e72dc28c 1035 return SvPVX(sv);
46fc3d4c 1036}
a687059c 1037
5a844595
GS
1038#if defined(PERL_IMPLICIT_CONTEXT)
1039SV *
1040Perl_mess_nocontext(const char *pat, ...)
1041{
1042 dTHX;
1043 SV *retval;
1044 va_list args;
1045 va_start(args, pat);
1046 retval = vmess(pat, &args);
1047 va_end(args);
1048 return retval;
1049}
1050#endif /* PERL_IMPLICIT_CONTEXT */
1051
06bf62c7 1052SV *
5a844595
GS
1053Perl_mess(pTHX_ const char *pat, ...)
1054{
1055 SV *retval;
1056 va_list args;
1057 va_start(args, pat);
1058 retval = vmess(pat, &args);
1059 va_end(args);
1060 return retval;
1061}
1062
5f66b61c
AL
1063STATIC const COP*
1064S_closest_cop(pTHX_ const COP *cop, const OP *o)
ae7d165c 1065{
97aff369 1066 dVAR;
ae7d165c
PJ
1067 /* Look for PL_op starting from o. cop is the last COP we've seen. */
1068
fabdb6c0
AL
1069 if (!o || o == PL_op)
1070 return cop;
ae7d165c
PJ
1071
1072 if (o->op_flags & OPf_KIDS) {
5f66b61c 1073 const OP *kid;
fabdb6c0 1074 for (kid = cUNOPo->op_first; kid; kid = kid->op_sibling) {
5f66b61c 1075 const COP *new_cop;
ae7d165c
PJ
1076
1077 /* If the OP_NEXTSTATE has been optimised away we can still use it
1078 * the get the file and line number. */
1079
1080 if (kid->op_type == OP_NULL && kid->op_targ == OP_NEXTSTATE)
5f66b61c 1081 cop = (const COP *)kid;
ae7d165c
PJ
1082
1083 /* Keep searching, and return when we've found something. */
1084
1085 new_cop = closest_cop(cop, kid);
fabdb6c0
AL
1086 if (new_cop)
1087 return new_cop;
ae7d165c
PJ
1088 }
1089 }
1090
1091 /* Nothing found. */
1092
5f66b61c 1093 return NULL;
ae7d165c
PJ
1094}
1095
5a844595
GS
1096SV *
1097Perl_vmess(pTHX_ const char *pat, va_list *args)
46fc3d4c 1098{
97aff369 1099 dVAR;
c4420975 1100 SV * const sv = mess_alloc();
46fc3d4c 1101
5f66b61c 1102 sv_vsetpvfn(sv, pat, strlen(pat), args, NULL, 0, NULL);
46fc3d4c 1103 if (!SvCUR(sv) || *(SvEND(sv) - 1) != '\n') {
ae7d165c
PJ
1104 /*
1105 * Try and find the file and line for PL_op. This will usually be
1106 * PL_curcop, but it might be a cop that has been optimised away. We
1107 * can try to find such a cop by searching through the optree starting
1108 * from the sibling of PL_curcop.
1109 */
1110
e1ec3a88 1111 const COP *cop = closest_cop(PL_curcop, PL_curcop->op_sibling);
5f66b61c
AL
1112 if (!cop)
1113 cop = PL_curcop;
ae7d165c
PJ
1114
1115 if (CopLINE(cop))
ed094faf 1116 Perl_sv_catpvf(aTHX_ sv, " at %s line %"IVdf,
3aed30dc 1117 OutCopFILE(cop), (IV)CopLINE(cop));
2035c5e8 1118 if (GvIO(PL_last_in_gv) && IoLINES(GvIOp(PL_last_in_gv))) {
e1ec3a88 1119 const bool line_mode = (RsSIMPLE(PL_rs) &&
95a20fc0 1120 SvCUR(PL_rs) == 1 && *SvPVX_const(PL_rs) == '\n');
57def98f 1121 Perl_sv_catpvf(aTHX_ sv, ", <%s> %s %"IVdf,
5f66b61c 1122 PL_last_in_gv == PL_argvgv ? "" : GvNAME(PL_last_in_gv),
edc2eac3
JH
1123 line_mode ? "line" : "chunk",
1124 (IV)IoLINES(GvIOp(PL_last_in_gv)));
a687059c 1125 }
5f66b61c
AL
1126 if (PL_dirty)
1127 sv_catpvs(sv, " during global destruction");
1128 sv_catpvs(sv, ".\n");
a687059c 1129 }
06bf62c7 1130 return sv;
a687059c
LW
1131}
1132
7ff03255
SG
1133void
1134Perl_write_to_stderr(pTHX_ const char* message, int msglen)
1135{
27da23d5 1136 dVAR;
7ff03255
SG
1137 IO *io;
1138 MAGIC *mg;
1139
1140 if (PL_stderrgv && SvREFCNT(PL_stderrgv)
1141 && (io = GvIO(PL_stderrgv))
1142 && (mg = SvTIED_mg((SV*)io, PERL_MAGIC_tiedscalar)))
1143 {
1144 dSP;
1145 ENTER;
1146 SAVETMPS;
1147
1148 save_re_context();
1149 SAVESPTR(PL_stderrgv);
a0714e2c 1150 PL_stderrgv = NULL;
7ff03255
SG
1151
1152 PUSHSTACKi(PERLSI_MAGIC);
1153
1154 PUSHMARK(SP);
1155 EXTEND(SP,2);
1156 PUSHs(SvTIED_obj((SV*)io, mg));
1157 PUSHs(sv_2mortal(newSVpvn(message, msglen)));
1158 PUTBACK;
1159 call_method("PRINT", G_SCALAR);
1160
1161 POPSTACK;
1162 FREETMPS;
1163 LEAVE;
1164 }
1165 else {
1166#ifdef USE_SFIO
1167 /* SFIO can really mess with your errno */
53c1dcc0 1168 const int e = errno;
7ff03255 1169#endif
53c1dcc0 1170 PerlIO * const serr = Perl_error_log;
7ff03255
SG
1171
1172 PERL_WRITE_MSG_TO_CONSOLE(serr, message, msglen);
1173 (void)PerlIO_flush(serr);
1174#ifdef USE_SFIO
1175 errno = e;
1176#endif
1177 }
1178}
1179
46d9c920 1180/* Common code used by vcroak, vdie, vwarn and vwarner */
3ab1ac99 1181
46d9c920
NC
1182STATIC bool
1183S_vdie_common(pTHX_ const char *message, STRLEN msglen, I32 utf8, bool warn)
63315e18 1184{
97aff369 1185 dVAR;
63315e18
NC
1186 HV *stash;
1187 GV *gv;
1188 CV *cv;
46d9c920
NC
1189 SV **const hook = warn ? &PL_warnhook : &PL_diehook;
1190 /* sv_2cv might call Perl_croak() or Perl_warner() */
1191 SV * const oldhook = *hook;
1192
1193 assert(oldhook);
63315e18 1194
63315e18 1195 ENTER;
46d9c920
NC
1196 SAVESPTR(*hook);
1197 *hook = NULL;
1198 cv = sv_2cv(oldhook, &stash, &gv, 0);
63315e18
NC
1199 LEAVE;
1200 if (cv && !CvDEPTH(cv) && (CvROOT(cv) || CvXSUB(cv))) {
1201 dSP;
1202 SV *msg;
1203
1204 ENTER;
1205 save_re_context();
46d9c920
NC
1206 if (warn) {
1207 SAVESPTR(*hook);
1208 *hook = NULL;
1209 }
1210 if (warn || message) {
63315e18
NC
1211 msg = newSVpvn(message, msglen);
1212 SvFLAGS(msg) |= utf8;
1213 SvREADONLY_on(msg);
1214 SAVEFREESV(msg);
1215 }
1216 else {
1217 msg = ERRSV;
1218 }
1219
46d9c920 1220 PUSHSTACKi(warn ? PERLSI_WARNHOOK : PERLSI_DIEHOOK);
63315e18
NC
1221 PUSHMARK(SP);
1222 XPUSHs(msg);
1223 PUTBACK;
1224 call_sv((SV*)cv, G_DISCARD);
1225 POPSTACK;
1226 LEAVE;
46d9c920 1227 return TRUE;
63315e18 1228 }
46d9c920 1229 return FALSE;
63315e18
NC
1230}
1231
cfd0369c 1232STATIC const char *
e07360fa
AT
1233S_vdie_croak_common(pTHX_ const char* pat, va_list* args, STRLEN* msglen,
1234 I32* utf8)
1235{
1236 dVAR;
cfd0369c 1237 const char *message;
e07360fa
AT
1238
1239 if (pat) {
890ce7af 1240 SV * const msv = vmess(pat, args);
e07360fa
AT
1241 if (PL_errors && SvCUR(PL_errors)) {
1242 sv_catsv(PL_errors, msv);
cfd0369c 1243 message = SvPV_const(PL_errors, *msglen);
e07360fa
AT
1244 SvCUR_set(PL_errors, 0);
1245 }
1246 else
cfd0369c 1247 message = SvPV_const(msv,*msglen);
e07360fa
AT
1248 *utf8 = SvUTF8(msv);
1249 }
1250 else {
bd61b366 1251 message = NULL;
e07360fa
AT
1252 }
1253
1254 DEBUG_S(PerlIO_printf(Perl_debug_log,
1255 "%p: die/croak: message = %s\ndiehook = %p\n",
1256 thr, message, PL_diehook));
1257 if (PL_diehook) {
46d9c920 1258 S_vdie_common(aTHX_ message, *msglen, *utf8, FALSE);
e07360fa
AT
1259 }
1260 return message;
1261}
1262
c5be433b
GS
1263OP *
1264Perl_vdie(pTHX_ const char* pat, va_list *args)
36477c24 1265{
97aff369 1266 dVAR;
73d840c0 1267 const char *message;
e1ec3a88 1268 const int was_in_eval = PL_in_eval;
06bf62c7 1269 STRLEN msglen;
ff882698 1270 I32 utf8 = 0;
36477c24 1271
bf49b057 1272 DEBUG_S(PerlIO_printf(Perl_debug_log,
199100c8 1273 "%p: die: curstack = %p, mainstack = %p\n",
533c011a 1274 thr, PL_curstack, PL_mainstack));
36477c24 1275
890ce7af 1276 message = vdie_croak_common(pat, args, &msglen, &utf8);
36477c24 1277
06bf62c7 1278 PL_restartop = die_where(message, msglen);
ff882698 1279 SvFLAGS(ERRSV) |= utf8;
bf49b057 1280 DEBUG_S(PerlIO_printf(Perl_debug_log,
7c06b590 1281 "%p: die: restartop = %p, was_in_eval = %d, top_env = %p\n",
533c011a 1282 thr, PL_restartop, was_in_eval, PL_top_env));
3280af22 1283 if ((!PL_restartop && was_in_eval) || PL_top_env->je_prev)
6224f72b 1284 JMPENV_JUMP(3);
3280af22 1285 return PL_restartop;
36477c24 1286}
1287
c5be433b 1288#if defined(PERL_IMPLICIT_CONTEXT)
cea2e8a9
GS
1289OP *
1290Perl_die_nocontext(const char* pat, ...)
a687059c 1291{
cea2e8a9
GS
1292 dTHX;
1293 OP *o;
a687059c 1294 va_list args;
cea2e8a9 1295 va_start(args, pat);
c5be433b 1296 o = vdie(pat, &args);
cea2e8a9
GS
1297 va_end(args);
1298 return o;
1299}
c5be433b 1300#endif /* PERL_IMPLICIT_CONTEXT */
cea2e8a9
GS
1301
1302OP *
1303Perl_die(pTHX_ const char* pat, ...)
1304{
1305 OP *o;
1306 va_list args;
1307 va_start(args, pat);
c5be433b 1308 o = vdie(pat, &args);
cea2e8a9
GS
1309 va_end(args);
1310 return o;
1311}
1312
c5be433b
GS
1313void
1314Perl_vcroak(pTHX_ const char* pat, va_list *args)
cea2e8a9 1315{
97aff369 1316 dVAR;
73d840c0 1317 const char *message;
06bf62c7 1318 STRLEN msglen;
ff882698 1319 I32 utf8 = 0;
a687059c 1320
3ab1ac99 1321 message = S_vdie_croak_common(aTHX_ pat, args, &msglen, &utf8);
5a844595 1322
3280af22 1323 if (PL_in_eval) {
06bf62c7 1324 PL_restartop = die_where(message, msglen);
ff882698 1325 SvFLAGS(ERRSV) |= utf8;
6224f72b 1326 JMPENV_JUMP(3);
a0d0e21e 1327 }
84414e3e 1328 else if (!message)
cfd0369c 1329 message = SvPVx_const(ERRSV, msglen);
84414e3e 1330
7ff03255 1331 write_to_stderr(message, msglen);
f86702cc 1332 my_failure_exit();
a687059c
LW
1333}
1334
c5be433b 1335#if defined(PERL_IMPLICIT_CONTEXT)
8990e307 1336void
cea2e8a9 1337Perl_croak_nocontext(const char *pat, ...)
a687059c 1338{
cea2e8a9 1339 dTHX;
a687059c 1340 va_list args;
cea2e8a9 1341 va_start(args, pat);
c5be433b 1342 vcroak(pat, &args);
cea2e8a9
GS
1343 /* NOTREACHED */
1344 va_end(args);
1345}
1346#endif /* PERL_IMPLICIT_CONTEXT */
1347
954c1994 1348/*
ccfc67b7
JH
1349=head1 Warning and Dieing
1350
954c1994
GS
1351=for apidoc croak
1352
9983fa3c 1353This is the XSUB-writer's interface to Perl's C<die> function.
966353fd
MF
1354Normally call this function the same way you call the C C<printf>
1355function. Calling C<croak> returns control directly to Perl,
1356sidestepping the normal C order of execution. See C<warn>.
9983fa3c
GS
1357
1358If you want to throw an exception object, assign the object to
bd61b366 1359C<$@> and then pass C<NULL> to croak():
9983fa3c
GS
1360
1361 errsv = get_sv("@", TRUE);
1362 sv_setsv(errsv, exception_object);
bd61b366 1363 croak(NULL);
954c1994
GS
1364
1365=cut
1366*/
1367
cea2e8a9
GS
1368void
1369Perl_croak(pTHX_ const char *pat, ...)
1370{
1371 va_list args;
1372 va_start(args, pat);
c5be433b 1373 vcroak(pat, &args);
cea2e8a9
GS
1374 /* NOTREACHED */
1375 va_end(args);
1376}
1377
c5be433b
GS
1378void
1379Perl_vwarn(pTHX_ const char* pat, va_list *args)
cea2e8a9 1380{
27da23d5 1381 dVAR;
06bf62c7 1382 STRLEN msglen;
53c1dcc0
AL
1383 SV * const msv = vmess(pat, args);
1384 const I32 utf8 = SvUTF8(msv);
1385 const char * const message = SvPV_const(msv, msglen);
a687059c 1386
3280af22 1387 if (PL_warnhook) {
46d9c920 1388 if (vdie_common(message, msglen, utf8, TRUE))
20cec16a 1389 return;
748a9306 1390 }
87582a92 1391
7ff03255 1392 write_to_stderr(message, msglen);
a687059c 1393}
8d063cd8 1394
c5be433b 1395#if defined(PERL_IMPLICIT_CONTEXT)
cea2e8a9
GS
1396void
1397Perl_warn_nocontext(const char *pat, ...)
1398{
1399 dTHX;
1400 va_list args;
1401 va_start(args, pat);
c5be433b 1402 vwarn(pat, &args);
cea2e8a9
GS
1403 va_end(args);
1404}
1405#endif /* PERL_IMPLICIT_CONTEXT */
1406
954c1994
GS
1407/*
1408=for apidoc warn
1409
966353fd
MF
1410This is the XSUB-writer's interface to Perl's C<warn> function. Call this
1411function the same way you call the C C<printf> function. See C<croak>.
954c1994
GS
1412
1413=cut
1414*/
1415
cea2e8a9
GS
1416void
1417Perl_warn(pTHX_ const char *pat, ...)
1418{
1419 va_list args;
1420 va_start(args, pat);
c5be433b 1421 vwarn(pat, &args);
cea2e8a9
GS
1422 va_end(args);
1423}
1424
c5be433b
GS
1425#if defined(PERL_IMPLICIT_CONTEXT)
1426void
1427Perl_warner_nocontext(U32 err, const char *pat, ...)
1428{
27da23d5 1429 dTHX;
c5be433b
GS
1430 va_list args;
1431 va_start(args, pat);
1432 vwarner(err, pat, &args);
1433 va_end(args);
1434}
1435#endif /* PERL_IMPLICIT_CONTEXT */
1436
599cee73 1437void
864dbfa3 1438Perl_warner(pTHX_ U32 err, const char* pat,...)
599cee73
PM
1439{
1440 va_list args;
c5be433b
GS
1441 va_start(args, pat);
1442 vwarner(err, pat, &args);
1443 va_end(args);
1444}
1445
1446void
1447Perl_vwarner(pTHX_ U32 err, const char* pat, va_list* args)
1448{
27da23d5 1449 dVAR;
d13b0d77 1450 if (ckDEAD(err)) {
a3b680e6 1451 SV * const msv = vmess(pat, args);
d13b0d77 1452 STRLEN msglen;
7452cf6a 1453 const char * const message = SvPV_const(msv, msglen);
a3b680e6 1454 const I32 utf8 = SvUTF8(msv);
599cee73 1455
3aed30dc 1456 if (PL_diehook) {
63315e18 1457 assert(message);
46d9c920 1458 S_vdie_common(aTHX_ message, msglen, utf8, FALSE);
3aed30dc
HS
1459 }
1460 if (PL_in_eval) {
1461 PL_restartop = die_where(message, msglen);
ff882698 1462 SvFLAGS(ERRSV) |= utf8;
3aed30dc
HS
1463 JMPENV_JUMP(3);
1464 }
7ff03255 1465 write_to_stderr(message, msglen);
3aed30dc 1466 my_failure_exit();
599cee73
PM
1467 }
1468 else {
d13b0d77 1469 Perl_vwarn(aTHX_ pat, args);
599cee73
PM
1470 }
1471}
1472
f54ba1c2
DM
1473/* implements the ckWARN? macros */
1474
1475bool
1476Perl_ckwarn(pTHX_ U32 w)
1477{
97aff369 1478 dVAR;
f54ba1c2
DM
1479 return
1480 (
1481 isLEXWARN_on
1482 && PL_curcop->cop_warnings != pWARN_NONE
1483 && (
1484 PL_curcop->cop_warnings == pWARN_ALL
1485 || isWARN_on(PL_curcop->cop_warnings, unpackWARN1(w))
1486 || (unpackWARN2(w) &&
1487 isWARN_on(PL_curcop->cop_warnings, unpackWARN2(w)))
1488 || (unpackWARN3(w) &&
1489 isWARN_on(PL_curcop->cop_warnings, unpackWARN3(w)))
1490 || (unpackWARN4(w) &&
1491 isWARN_on(PL_curcop->cop_warnings, unpackWARN4(w)))
1492 )
1493 )
1494 ||
1495 (
1496 isLEXWARN_off && PL_dowarn & G_WARN_ON
1497 )
1498 ;
1499}
1500
1501/* implements the ckWARN?_d macro */
1502
1503bool
1504Perl_ckwarn_d(pTHX_ U32 w)
1505{
97aff369 1506 dVAR;
f54ba1c2
DM
1507 return
1508 isLEXWARN_off
1509 || PL_curcop->cop_warnings == pWARN_ALL
1510 || (
1511 PL_curcop->cop_warnings != pWARN_NONE
1512 && (
1513 isWARN_on(PL_curcop->cop_warnings, unpackWARN1(w))
1514 || (unpackWARN2(w) &&
1515 isWARN_on(PL_curcop->cop_warnings, unpackWARN2(w)))
1516 || (unpackWARN3(w) &&
1517 isWARN_on(PL_curcop->cop_warnings, unpackWARN3(w)))
1518 || (unpackWARN4(w) &&
1519 isWARN_on(PL_curcop->cop_warnings, unpackWARN4(w)))
1520 )
1521 )
1522 ;
1523}
1524
1525
1526
e6587932
DM
1527/* since we've already done strlen() for both nam and val
1528 * we can use that info to make things faster than
1529 * sprintf(s, "%s=%s", nam, val)
1530 */
1531#define my_setenv_format(s, nam, nlen, val, vlen) \
1532 Copy(nam, s, nlen, char); \
1533 *(s+nlen) = '='; \
1534 Copy(val, s+(nlen+1), vlen, char); \
1535 *(s+(nlen+1+vlen)) = '\0'
1536
13b6e58c 1537#ifdef USE_ENVIRON_ARRAY
eccd403f 1538 /* VMS' my_setenv() is in vms.c */
2986a63f 1539#if !defined(WIN32) && !defined(NETWARE)
8d063cd8 1540void
e1ec3a88 1541Perl_my_setenv(pTHX_ const char *nam, const char *val)
8d063cd8 1542{
27da23d5 1543 dVAR;
4efc5df6
GS
1544#ifdef USE_ITHREADS
1545 /* only parent thread can modify process environment */
1546 if (PL_curinterp == aTHX)
1547#endif
1548 {
f2517201 1549#ifndef PERL_USE_SAFE_PUTENV
50acdf95 1550 if (!PL_use_safe_putenv) {
f2517201 1551 /* most putenv()s leak, so we manipulate environ directly */
79072805 1552 register I32 i=setenv_getix(nam); /* where does it go? */
e6587932 1553 int nlen, vlen;
8d063cd8 1554
3280af22 1555 if (environ == PL_origenviron) { /* need we copy environment? */
79072805
LW
1556 I32 j;
1557 I32 max;
fe14fcc3
LW
1558 char **tmpenv;
1559
1560 for (max = i; environ[max]; max++) ;
f2517201
GS
1561 tmpenv = (char**)safesysmalloc((max+2) * sizeof(char*));
1562 for (j=0; j<max; j++) { /* copy environment */
e1ec3a88 1563 const int len = strlen(environ[j]);
3aed30dc
HS
1564 tmpenv[j] = (char*)safesysmalloc((len+1)*sizeof(char));
1565 Copy(environ[j], tmpenv[j], len+1, char);
f2517201 1566 }
bd61b366 1567 tmpenv[max] = NULL;
fe14fcc3
LW
1568 environ = tmpenv; /* tell exec where it is now */
1569 }
a687059c 1570 if (!val) {
f2517201 1571 safesysfree(environ[i]);
a687059c
LW
1572 while (environ[i]) {
1573 environ[i] = environ[i+1];
1574 i++;
1575 }
1576 return;
1577 }
8d063cd8 1578 if (!environ[i]) { /* does not exist yet */
f2517201 1579 environ = (char**)safesysrealloc(environ, (i+2) * sizeof(char*));
bd61b366 1580 environ[i+1] = NULL; /* make sure it's null terminated */
8d063cd8 1581 }
fe14fcc3 1582 else
f2517201 1583 safesysfree(environ[i]);
e6587932
DM
1584 nlen = strlen(nam);
1585 vlen = strlen(val);
f2517201 1586
e6587932
DM
1587 environ[i] = (char*)safesysmalloc((nlen+vlen+2) * sizeof(char));
1588 /* all that work just for this */
1589 my_setenv_format(environ[i], nam, nlen, val, vlen);
50acdf95
MS
1590 } else {
1591# endif
a0fd4948 1592# if defined(__CYGWIN__) || defined(EPOC) || defined(__SYMBIAN32__)
88f5bc07
AB
1593# if defined(HAS_UNSETENV)
1594 if (val == NULL) {
1595 (void)unsetenv(nam);
1596 } else {
1597 (void)setenv(nam, val, 1);
1598 }
1599# else /* ! HAS_UNSETENV */
1600 (void)setenv(nam, val, 1);
1601# endif /* HAS_UNSETENV */
47dafe4d 1602# else
88f5bc07
AB
1603# if defined(HAS_UNSETENV)
1604 if (val == NULL) {
1605 (void)unsetenv(nam);
1606 } else {
c4420975
AL
1607 const int nlen = strlen(nam);
1608 const int vlen = strlen(val);
1609 char * const new_env =
88f5bc07
AB
1610 (char*)safesysmalloc((nlen + vlen + 2) * sizeof(char));
1611 my_setenv_format(new_env, nam, nlen, val, vlen);
1612 (void)putenv(new_env);
1613 }
1614# else /* ! HAS_UNSETENV */
1615 char *new_env;
c4420975
AL
1616 const int nlen = strlen(nam);
1617 int vlen;
88f5bc07
AB
1618 if (!val) {
1619 val = "";
1620 }
1621 vlen = strlen(val);
1622 new_env = (char*)safesysmalloc((nlen + vlen + 2) * sizeof(char));
1623 /* all that work just for this */
1624 my_setenv_format(new_env, nam, nlen, val, vlen);
1625 (void)putenv(new_env);
1626# endif /* HAS_UNSETENV */
47dafe4d 1627# endif /* __CYGWIN__ */
50acdf95
MS
1628#ifndef PERL_USE_SAFE_PUTENV
1629 }
1630#endif
4efc5df6 1631 }
8d063cd8
LW
1632}
1633
2986a63f 1634#else /* WIN32 || NETWARE */
68dc0745 1635
1636void
72229eff 1637Perl_my_setenv(pTHX_ const char *nam, const char *val)
68dc0745 1638{
27da23d5 1639 dVAR;
ac5c734f 1640 register char *envstr;
e1ec3a88
AL
1641 const int nlen = strlen(nam);
1642 int vlen;
e6587932 1643
ac5c734f
GS
1644 if (!val) {
1645 val = "";
1646 }
e6587932 1647 vlen = strlen(val);
a02a5408 1648 Newx(envstr, nlen+vlen+2, char);
e6587932 1649 my_setenv_format(envstr, nam, nlen, val, vlen);
ac5c734f
GS
1650 (void)PerlEnv_putenv(envstr);
1651 Safefree(envstr);
3e3baf6d
TB
1652}
1653
2986a63f 1654#endif /* WIN32 || NETWARE */
3e3baf6d 1655
2f42fcb0 1656#ifndef PERL_MICRO
3e3baf6d 1657I32
e1ec3a88 1658Perl_setenv_getix(pTHX_ const char *nam)
3e3baf6d 1659{
53c1dcc0 1660 register I32 i;
0d46e09a 1661 register const I32 len = strlen(nam);
3e3baf6d
TB
1662
1663 for (i = 0; environ[i]; i++) {
1664 if (
1665#ifdef WIN32
1666 strnicmp(environ[i],nam,len) == 0
1667#else
1668 strnEQ(environ[i],nam,len)
1669#endif
1670 && environ[i][len] == '=')
1671 break; /* strnEQ must come first to avoid */
1672 } /* potential SEGV's */
1673 return i;
68dc0745 1674}
2f42fcb0 1675#endif /* !PERL_MICRO */
68dc0745 1676
ed79a026 1677#endif /* !VMS && !EPOC*/
378cc40b 1678
16d20bd9 1679#ifdef UNLINK_ALL_VERSIONS
79072805 1680I32
6e732051 1681Perl_unlnk(pTHX_ const char *f) /* unlink all versions of a file */
378cc40b 1682{
79072805 1683 I32 i;
378cc40b 1684
6ad3d225 1685 for (i = 0; PerlLIO_unlink(f) >= 0; i++) ;
378cc40b
LW
1686 return i ? 0 : -1;
1687}
1688#endif
1689
7a3f2258 1690/* this is a drop-in replacement for bcopy() */
2253333f 1691#if (!defined(HAS_MEMCPY) && !defined(HAS_BCOPY)) || (!defined(HAS_MEMMOVE) && !defined(HAS_SAFE_MEMCPY) && !defined(HAS_SAFE_BCOPY))
378cc40b 1692char *
7a3f2258 1693Perl_my_bcopy(register const char *from,register char *to,register I32 len)
378cc40b 1694{
2d03de9c 1695 char * const retval = to;
378cc40b 1696
7c0587c8
LW
1697 if (from - to >= 0) {
1698 while (len--)
1699 *to++ = *from++;
1700 }
1701 else {
1702 to += len;
1703 from += len;
1704 while (len--)
faf8582f 1705 *(--to) = *(--from);
7c0587c8 1706 }
378cc40b
LW
1707 return retval;
1708}
ffed7fef 1709#endif
378cc40b 1710
7a3f2258 1711/* this is a drop-in replacement for memset() */
fc36a67e 1712#ifndef HAS_MEMSET
1713void *
7a3f2258 1714Perl_my_memset(register char *loc, register I32 ch, register I32 len)
fc36a67e 1715{
2d03de9c 1716 char * const retval = loc;
fc36a67e 1717
1718 while (len--)
1719 *loc++ = ch;
1720 return retval;
1721}
1722#endif
1723
7a3f2258 1724/* this is a drop-in replacement for bzero() */
7c0587c8 1725#if !defined(HAS_BZERO) && !defined(HAS_MEMSET)
378cc40b 1726char *
7a3f2258 1727Perl_my_bzero(register char *loc, register I32 len)
378cc40b 1728{
2d03de9c 1729 char * const retval = loc;
378cc40b
LW
1730
1731 while (len--)
1732 *loc++ = 0;
1733 return retval;
1734}
1735#endif
7c0587c8 1736
7a3f2258 1737/* this is a drop-in replacement for memcmp() */
36477c24 1738#if !defined(HAS_MEMCMP) || !defined(HAS_SANE_MEMCMP)
79072805 1739I32
7a3f2258 1740Perl_my_memcmp(const char *s1, const char *s2, register I32 len)
7c0587c8 1741{
e1ec3a88
AL
1742 register const U8 *a = (const U8 *)s1;
1743 register const U8 *b = (const U8 *)s2;
79072805 1744 register I32 tmp;
7c0587c8
LW
1745
1746 while (len--) {
27da23d5 1747 if ((tmp = *a++ - *b++))
7c0587c8
LW
1748 return tmp;
1749 }
1750 return 0;
1751}
36477c24 1752#endif /* !HAS_MEMCMP || !HAS_SANE_MEMCMP */
a687059c 1753
fe14fcc3 1754#ifndef HAS_VPRINTF
a687059c 1755
85e6fe83 1756#ifdef USE_CHAR_VSPRINTF
a687059c
LW
1757char *
1758#else
1759int
1760#endif
08105a92 1761vsprintf(char *dest, const char *pat, char *args)
a687059c
LW
1762{
1763 FILE fakebuf;
1764
1765 fakebuf._ptr = dest;
1766 fakebuf._cnt = 32767;
35c8bce7
LW
1767#ifndef _IOSTRG
1768#define _IOSTRG 0
1769#endif
a687059c
LW
1770 fakebuf._flag = _IOWRT|_IOSTRG;
1771 _doprnt(pat, args, &fakebuf); /* what a kludge */
1772 (void)putc('\0', &fakebuf);
85e6fe83 1773#ifdef USE_CHAR_VSPRINTF
a687059c
LW
1774 return(dest);
1775#else
1776 return 0; /* perl doesn't use return value */
1777#endif
1778}
1779
fe14fcc3 1780#endif /* HAS_VPRINTF */
a687059c
LW
1781
1782#ifdef MYSWAP
ffed7fef 1783#if BYTEORDER != 0x4321
a687059c 1784short
864dbfa3 1785Perl_my_swap(pTHX_ short s)
a687059c
LW
1786{
1787#if (BYTEORDER & 1) == 0
1788 short result;
1789
1790 result = ((s & 255) << 8) + ((s >> 8) & 255);
1791 return result;
1792#else
1793 return s;
1794#endif
1795}
1796
1797long
864dbfa3 1798Perl_my_htonl(pTHX_ long l)
a687059c
LW
1799{
1800 union {
1801 long result;
ffed7fef 1802 char c[sizeof(long)];
a687059c
LW
1803 } u;
1804
ffed7fef 1805#if BYTEORDER == 0x1234
a687059c
LW
1806 u.c[0] = (l >> 24) & 255;
1807 u.c[1] = (l >> 16) & 255;
1808 u.c[2] = (l >> 8) & 255;
1809 u.c[3] = l & 255;
1810 return u.result;
1811#else
ffed7fef 1812#if ((BYTEORDER - 0x1111) & 0x444) || !(BYTEORDER & 0xf)
cea2e8a9 1813 Perl_croak(aTHX_ "Unknown BYTEORDER\n");
a687059c 1814#else
79072805
LW
1815 register I32 o;
1816 register I32 s;
a687059c 1817
ffed7fef
LW
1818 for (o = BYTEORDER - 0x1111, s = 0; s < (sizeof(long)*8); o >>= 4, s += 8) {
1819 u.c[o & 0xf] = (l >> s) & 255;
a687059c
LW
1820 }
1821 return u.result;
1822#endif
1823#endif
1824}
1825
1826long
864dbfa3 1827Perl_my_ntohl(pTHX_ long l)
a687059c
LW
1828{
1829 union {
1830 long l;
ffed7fef 1831 char c[sizeof(long)];
a687059c
LW
1832 } u;
1833
ffed7fef 1834#if BYTEORDER == 0x1234
a687059c
LW
1835 u.c[0] = (l >> 24) & 255;
1836 u.c[1] = (l >> 16) & 255;
1837 u.c[2] = (l >> 8) & 255;
1838 u.c[3] = l & 255;
1839 return u.l;
1840#else
ffed7fef 1841#if ((BYTEORDER - 0x1111) & 0x444) || !(BYTEORDER & 0xf)
cea2e8a9 1842 Perl_croak(aTHX_ "Unknown BYTEORDER\n");
a687059c 1843#else
79072805
LW
1844 register I32 o;
1845 register I32 s;
a687059c
LW
1846
1847 u.l = l;
1848 l = 0;
ffed7fef
LW
1849 for (o = BYTEORDER - 0x1111, s = 0; s < (sizeof(long)*8); o >>= 4, s += 8) {
1850 l |= (u.c[o & 0xf] & 255) << s;
a687059c
LW
1851 }
1852 return l;
1853#endif
1854#endif
1855}
1856
ffed7fef 1857#endif /* BYTEORDER != 0x4321 */
988174c1
LW
1858#endif /* MYSWAP */
1859
1860/*
1861 * Little-endian byte order functions - 'v' for 'VAX', or 'reVerse'.
1862 * If these functions are defined,
1863 * the BYTEORDER is neither 0x1234 nor 0x4321.
1864 * However, this is not assumed.
1865 * -DWS
1866 */
1867
1109a392 1868#define HTOLE(name,type) \
988174c1 1869 type \
ba106d47 1870 name (register type n) \
988174c1
LW
1871 { \
1872 union { \
1873 type value; \
1874 char c[sizeof(type)]; \
1875 } u; \
79072805 1876 register I32 i; \
1109a392
MHM
1877 register I32 s = 0; \
1878 for (i = 0; i < sizeof(u.c); i++, s += 8) { \
988174c1
LW
1879 u.c[i] = (n >> s) & 0xFF; \
1880 } \
1881 return u.value; \
1882 }
1883
1109a392 1884#define LETOH(name,type) \
988174c1 1885 type \
ba106d47 1886 name (register type n) \
988174c1
LW
1887 { \
1888 union { \
1889 type value; \
1890 char c[sizeof(type)]; \
1891 } u; \
79072805 1892 register I32 i; \
1109a392 1893 register I32 s = 0; \
988174c1
LW
1894 u.value = n; \
1895 n = 0; \
1109a392
MHM
1896 for (i = 0; i < sizeof(u.c); i++, s += 8) { \
1897 n |= ((type)(u.c[i] & 0xFF)) << s; \
988174c1
LW
1898 } \
1899 return n; \
1900 }
1901
1109a392
MHM
1902/*
1903 * Big-endian byte order functions.
1904 */
1905
1906#define HTOBE(name,type) \
1907 type \
1908 name (register type n) \
1909 { \
1910 union { \
1911 type value; \
1912 char c[sizeof(type)]; \
1913 } u; \
1914 register I32 i; \
1915 register I32 s = 8*(sizeof(u.c)-1); \
1916 for (i = 0; i < sizeof(u.c); i++, s -= 8) { \
1917 u.c[i] = (n >> s) & 0xFF; \
1918 } \
1919 return u.value; \
1920 }
1921
1922#define BETOH(name,type) \
1923 type \
1924 name (register type n) \
1925 { \
1926 union { \
1927 type value; \
1928 char c[sizeof(type)]; \
1929 } u; \
1930 register I32 i; \
1931 register I32 s = 8*(sizeof(u.c)-1); \
1932 u.value = n; \
1933 n = 0; \
1934 for (i = 0; i < sizeof(u.c); i++, s -= 8) { \
1935 n |= ((type)(u.c[i] & 0xFF)) << s; \
1936 } \
1937 return n; \
1938 }
1939
1940/*
1941 * If we just can't do it...
1942 */
1943
1944#define NOT_AVAIL(name,type) \
1945 type \
1946 name (register type n) \
1947 { \
1948 Perl_croak_nocontext(#name "() not available"); \
1949 return n; /* not reached */ \
1950 }
1951
1952
988174c1 1953#if defined(HAS_HTOVS) && !defined(htovs)
1109a392 1954HTOLE(htovs,short)
988174c1
LW
1955#endif
1956#if defined(HAS_HTOVL) && !defined(htovl)
1109a392 1957HTOLE(htovl,long)
988174c1
LW
1958#endif
1959#if defined(HAS_VTOHS) && !defined(vtohs)
1109a392 1960LETOH(vtohs,short)
988174c1
LW
1961#endif
1962#if defined(HAS_VTOHL) && !defined(vtohl)
1109a392
MHM
1963LETOH(vtohl,long)
1964#endif
1965
1966#ifdef PERL_NEED_MY_HTOLE16
1967# if U16SIZE == 2
1968HTOLE(Perl_my_htole16,U16)
1969# else
1970NOT_AVAIL(Perl_my_htole16,U16)
1971# endif
1972#endif
1973#ifdef PERL_NEED_MY_LETOH16
1974# if U16SIZE == 2
1975LETOH(Perl_my_letoh16,U16)
1976# else
1977NOT_AVAIL(Perl_my_letoh16,U16)
1978# endif
1979#endif
1980#ifdef PERL_NEED_MY_HTOBE16
1981# if U16SIZE == 2
1982HTOBE(Perl_my_htobe16,U16)
1983# else
1984NOT_AVAIL(Perl_my_htobe16,U16)
1985# endif
1986#endif
1987#ifdef PERL_NEED_MY_BETOH16
1988# if U16SIZE == 2
1989BETOH(Perl_my_betoh16,U16)
1990# else
1991NOT_AVAIL(Perl_my_betoh16,U16)
1992# endif
1993#endif
1994
1995#ifdef PERL_NEED_MY_HTOLE32
1996# if U32SIZE == 4
1997HTOLE(Perl_my_htole32,U32)
1998# else
1999NOT_AVAIL(Perl_my_htole32,U32)
2000# endif
2001#endif
2002#ifdef PERL_NEED_MY_LETOH32
2003# if U32SIZE == 4
2004LETOH(Perl_my_letoh32,U32)
2005# else
2006NOT_AVAIL(Perl_my_letoh32,U32)
2007# endif
2008#endif
2009#ifdef PERL_NEED_MY_HTOBE32
2010# if U32SIZE == 4
2011HTOBE(Perl_my_htobe32,U32)
2012# else
2013NOT_AVAIL(Perl_my_htobe32,U32)
2014# endif
2015#endif
2016#ifdef PERL_NEED_MY_BETOH32
2017# if U32SIZE == 4
2018BETOH(Perl_my_betoh32,U32)
2019# else
2020NOT_AVAIL(Perl_my_betoh32,U32)
2021# endif
2022#endif
2023
2024#ifdef PERL_NEED_MY_HTOLE64
2025# if U64SIZE == 8
2026HTOLE(Perl_my_htole64,U64)
2027# else
2028NOT_AVAIL(Perl_my_htole64,U64)
2029# endif
2030#endif
2031#ifdef PERL_NEED_MY_LETOH64
2032# if U64SIZE == 8
2033LETOH(Perl_my_letoh64,U64)
2034# else
2035NOT_AVAIL(Perl_my_letoh64,U64)
2036# endif
2037#endif
2038#ifdef PERL_NEED_MY_HTOBE64
2039# if U64SIZE == 8
2040HTOBE(Perl_my_htobe64,U64)
2041# else
2042NOT_AVAIL(Perl_my_htobe64,U64)
2043# endif
2044#endif
2045#ifdef PERL_NEED_MY_BETOH64
2046# if U64SIZE == 8
2047BETOH(Perl_my_betoh64,U64)
2048# else
2049NOT_AVAIL(Perl_my_betoh64,U64)
2050# endif
988174c1 2051#endif
a687059c 2052
1109a392
MHM
2053#ifdef PERL_NEED_MY_HTOLES
2054HTOLE(Perl_my_htoles,short)
2055#endif
2056#ifdef PERL_NEED_MY_LETOHS
2057LETOH(Perl_my_letohs,short)
2058#endif
2059#ifdef PERL_NEED_MY_HTOBES
2060HTOBE(Perl_my_htobes,short)
2061#endif
2062#ifdef PERL_NEED_MY_BETOHS
2063BETOH(Perl_my_betohs,short)
2064#endif
2065
2066#ifdef PERL_NEED_MY_HTOLEI
2067HTOLE(Perl_my_htolei,int)
2068#endif
2069#ifdef PERL_NEED_MY_LETOHI
2070LETOH(Perl_my_letohi,int)
2071#endif
2072#ifdef PERL_NEED_MY_HTOBEI
2073HTOBE(Perl_my_htobei,int)
2074#endif
2075#ifdef PERL_NEED_MY_BETOHI
2076BETOH(Perl_my_betohi,int)
2077#endif
2078
2079#ifdef PERL_NEED_MY_HTOLEL
2080HTOLE(Perl_my_htolel,long)
2081#endif
2082#ifdef PERL_NEED_MY_LETOHL
2083LETOH(Perl_my_letohl,long)
2084#endif
2085#ifdef PERL_NEED_MY_HTOBEL
2086HTOBE(Perl_my_htobel,long)
2087#endif
2088#ifdef PERL_NEED_MY_BETOHL
2089BETOH(Perl_my_betohl,long)
2090#endif
2091
2092void
2093Perl_my_swabn(void *ptr, int n)
2094{
2095 register char *s = (char *)ptr;
2096 register char *e = s + (n-1);
2097 register char tc;
2098
2099 for (n /= 2; n > 0; s++, e--, n--) {
2100 tc = *s;
2101 *s = *e;
2102 *e = tc;
2103 }
2104}
2105
4a7d1889
NIS
2106PerlIO *
2107Perl_my_popen_list(pTHX_ char *mode, int n, SV **args)
2108{
2986a63f 2109#if (!defined(DOSISH) || defined(HAS_FORK) || defined(AMIGAOS)) && !defined(OS2) && !defined(VMS) && !defined(__OPEN_VM) && !defined(EPOC) && !defined(MACOS_TRADITIONAL) && !defined(NETWARE)
97aff369 2110 dVAR;
1f852d0d
NIS
2111 int p[2];
2112 register I32 This, that;
2113 register Pid_t pid;
2114 SV *sv;
2115 I32 did_pipes = 0;
2116 int pp[2];
2117
2118 PERL_FLUSHALL_FOR_CHILD;
2119 This = (*mode == 'w');
2120 that = !This;
2121 if (PL_tainting) {
2122 taint_env();
2123 taint_proper("Insecure %s%s", "EXEC");
2124 }
2125 if (PerlProc_pipe(p) < 0)
2126 return Nullfp;
2127 /* Try for another pipe pair for error return */
2128 if (PerlProc_pipe(pp) >= 0)
2129 did_pipes = 1;
52e18b1f 2130 while ((pid = PerlProc_fork()) < 0) {
1f852d0d
NIS
2131 if (errno != EAGAIN) {
2132 PerlLIO_close(p[This]);
4e6dfe71 2133 PerlLIO_close(p[that]);
1f852d0d
NIS
2134 if (did_pipes) {
2135 PerlLIO_close(pp[0]);
2136 PerlLIO_close(pp[1]);
2137 }
2138 return Nullfp;
2139 }
2140 sleep(5);
2141 }
2142 if (pid == 0) {
2143 /* Child */
1f852d0d
NIS
2144#undef THIS
2145#undef THAT
2146#define THIS that
2147#define THAT This
1f852d0d
NIS
2148 /* Close parent's end of error status pipe (if any) */
2149 if (did_pipes) {
2150 PerlLIO_close(pp[0]);
2151#if defined(HAS_FCNTL) && defined(F_SETFD)
2152 /* Close error pipe automatically if exec works */
2153 fcntl(pp[1], F_SETFD, FD_CLOEXEC);
2154#endif
2155 }
2156 /* Now dup our end of _the_ pipe to right position */
2157 if (p[THIS] != (*mode == 'r')) {
2158 PerlLIO_dup2(p[THIS], *mode == 'r');
2159 PerlLIO_close(p[THIS]);
4e6dfe71
GS
2160 if (p[THAT] != (*mode == 'r')) /* if dup2() didn't close it */
2161 PerlLIO_close(p[THAT]); /* close parent's end of _the_ pipe */
1f852d0d 2162 }
4e6dfe71
GS
2163 else
2164 PerlLIO_close(p[THAT]); /* close parent's end of _the_ pipe */
1f852d0d
NIS
2165#if !defined(HAS_FCNTL) || !defined(F_SETFD)
2166 /* No automatic close - do it by hand */
b7953727
JH
2167# ifndef NOFILE
2168# define NOFILE 20
2169# endif
a080fe3d
NIS
2170 {
2171 int fd;
2172
2173 for (fd = PL_maxsysfd + 1; fd < NOFILE; fd++) {
3aed30dc 2174 if (fd != pp[1])
a080fe3d
NIS
2175 PerlLIO_close(fd);
2176 }
1f852d0d
NIS
2177 }
2178#endif
a0714e2c 2179 do_aexec5(NULL, args-1, args-1+n, pp[1], did_pipes);
1f852d0d
NIS
2180 PerlProc__exit(1);
2181#undef THIS
2182#undef THAT
2183 }
2184 /* Parent */
52e18b1f 2185 do_execfree(); /* free any memory malloced by child on fork */
1f852d0d
NIS
2186 if (did_pipes)
2187 PerlLIO_close(pp[1]);
2188 /* Keep the lower of the two fd numbers */
2189 if (p[that] < p[This]) {
2190 PerlLIO_dup2(p[This], p[that]);
2191 PerlLIO_close(p[This]);
2192 p[This] = p[that];
2193 }
4e6dfe71
GS
2194 else
2195 PerlLIO_close(p[that]); /* close child's end of pipe */
2196
1f852d0d
NIS
2197 LOCK_FDPID_MUTEX;
2198 sv = *av_fetch(PL_fdpid,p[This],TRUE);
2199 UNLOCK_FDPID_MUTEX;
862a34c6 2200 SvUPGRADE(sv,SVt_IV);
45977657 2201 SvIV_set(sv, pid);
1f852d0d
NIS
2202 PL_forkprocess = pid;
2203 /* If we managed to get status pipe check for exec fail */
2204 if (did_pipes && pid > 0) {
2205 int errkid;
2206 int n = 0, n1;
2207
2208 while (n < sizeof(int)) {
2209 n1 = PerlLIO_read(pp[0],
2210 (void*)(((char*)&errkid)+n),
2211 (sizeof(int)) - n);
2212 if (n1 <= 0)
2213 break;
2214 n += n1;
2215 }
2216 PerlLIO_close(pp[0]);
2217 did_pipes = 0;
2218 if (n) { /* Error */
2219 int pid2, status;
8c51524e 2220 PerlLIO_close(p[This]);
1f852d0d
NIS
2221 if (n != sizeof(int))
2222 Perl_croak(aTHX_ "panic: kid popen errno read");
2223 do {
2224 pid2 = wait4pid(pid, &status, 0);
2225 } while (pid2 == -1 && errno == EINTR);
2226 errno = errkid; /* Propagate errno from kid */
2227 return Nullfp;
2228 }
2229 }
2230 if (did_pipes)
2231 PerlLIO_close(pp[0]);
2232 return PerlIO_fdopen(p[This], mode);
2233#else
4a7d1889
NIS
2234 Perl_croak(aTHX_ "List form of piped open not implemented");
2235 return (PerlIO *) NULL;
1f852d0d 2236#endif
4a7d1889
NIS
2237}
2238
5f05dabc 2239 /* VMS' my_popen() is in VMS.c, same with OS/2. */
cd39f2b6 2240#if (!defined(DOSISH) || defined(HAS_FORK) || defined(AMIGAOS)) && !defined(VMS) && !defined(__OPEN_VM) && !defined(EPOC) && !defined(MACOS_TRADITIONAL)
760ac839 2241PerlIO *
3dd43144 2242Perl_my_popen(pTHX_ const char *cmd, const char *mode)
a687059c 2243{
97aff369 2244 dVAR;
a687059c 2245 int p[2];
8ac85365 2246 register I32 This, that;
d8a83dd3 2247 register Pid_t pid;
79072805 2248 SV *sv;
bfce84ec 2249 const I32 doexec = !(*cmd == '-' && cmd[1] == '\0');
e446cec8
IZ
2250 I32 did_pipes = 0;
2251 int pp[2];
a687059c 2252
45bc9206 2253 PERL_FLUSHALL_FOR_CHILD;
ddcf38b7
IZ
2254#ifdef OS2
2255 if (doexec) {
23da6c43 2256 return my_syspopen(aTHX_ cmd,mode);
ddcf38b7 2257 }
a1d180c4 2258#endif
8ac85365
NIS
2259 This = (*mode == 'w');
2260 that = !This;
3280af22 2261 if (doexec && PL_tainting) {
bbce6d69 2262 taint_env();
2263 taint_proper("Insecure %s%s", "EXEC");
d48672a2 2264 }
c2267164
IZ
2265 if (PerlProc_pipe(p) < 0)
2266 return Nullfp;
e446cec8
IZ
2267 if (doexec && PerlProc_pipe(pp) >= 0)
2268 did_pipes = 1;
52e18b1f 2269 while ((pid = PerlProc_fork()) < 0) {
a687059c 2270 if (errno != EAGAIN) {
6ad3d225 2271 PerlLIO_close(p[This]);
b5ac89c3 2272 PerlLIO_close(p[that]);
e446cec8
IZ
2273 if (did_pipes) {
2274 PerlLIO_close(pp[0]);
2275 PerlLIO_close(pp[1]);
2276 }
a687059c 2277 if (!doexec)
cea2e8a9 2278 Perl_croak(aTHX_ "Can't fork");
a687059c
LW
2279 return Nullfp;
2280 }
2281 sleep(5);
2282 }
2283 if (pid == 0) {
79072805
LW
2284 GV* tmpgv;
2285
30ac6d9b
GS
2286#undef THIS
2287#undef THAT
a687059c 2288#define THIS that
8ac85365 2289#define THAT This
e446cec8
IZ
2290 if (did_pipes) {
2291 PerlLIO_close(pp[0]);
2292#if defined(HAS_FCNTL) && defined(F_SETFD)
2293 fcntl(pp[1], F_SETFD, FD_CLOEXEC);
2294#endif
2295 }
a687059c 2296 if (p[THIS] != (*mode == 'r')) {
6ad3d225
GS
2297 PerlLIO_dup2(p[THIS], *mode == 'r');
2298 PerlLIO_close(p[THIS]);
b5ac89c3
NIS
2299 if (p[THAT] != (*mode == 'r')) /* if dup2() didn't close it */
2300 PerlLIO_close(p[THAT]);
a687059c 2301 }
b5ac89c3
NIS
2302 else
2303 PerlLIO_close(p[THAT]);
4435c477 2304#ifndef OS2
a687059c 2305 if (doexec) {
a0d0e21e 2306#if !defined(HAS_FCNTL) || !defined(F_SETFD)
ae986130
LW
2307#ifndef NOFILE
2308#define NOFILE 20
2309#endif
a080fe3d 2310 {
3aed30dc 2311 int fd;
a080fe3d
NIS
2312
2313 for (fd = PL_maxsysfd + 1; fd < NOFILE; fd++)
2314 if (fd != pp[1])
3aed30dc 2315 PerlLIO_close(fd);
a080fe3d 2316 }
ae986130 2317#endif
a080fe3d
NIS
2318 /* may or may not use the shell */
2319 do_exec3(cmd, pp[1], did_pipes);
6ad3d225 2320 PerlProc__exit(1);
a687059c 2321 }
4435c477 2322#endif /* defined OS2 */
fafc274c 2323 if ((tmpgv = gv_fetchpvs("$", GV_ADD|GV_NOTQUAL, SVt_PV))) {
4d76a344 2324 SvREADONLY_off(GvSV(tmpgv));
7766f137 2325 sv_setiv(GvSV(tmpgv), PerlProc_getpid());
4d76a344
RGS
2326 SvREADONLY_on(GvSV(tmpgv));
2327 }
2328#ifdef THREADS_HAVE_PIDS
2329 PL_ppid = (IV)getppid();
2330#endif
3280af22 2331 PL_forkprocess = 0;
ca0c25f6 2332#ifdef PERL_USES_PL_PIDSTATUS
3280af22 2333 hv_clear(PL_pidstatus); /* we have no children */
ca0c25f6 2334#endif
a687059c
LW
2335 return Nullfp;
2336#undef THIS
2337#undef THAT
2338 }
b5ac89c3 2339 do_execfree(); /* free any memory malloced by child on vfork */
e446cec8
IZ
2340 if (did_pipes)
2341 PerlLIO_close(pp[1]);
8ac85365 2342 if (p[that] < p[This]) {
6ad3d225
GS
2343 PerlLIO_dup2(p[This], p[that]);
2344 PerlLIO_close(p[This]);
8ac85365 2345 p[This] = p[that];
62b28dd9 2346 }
b5ac89c3
NIS
2347 else
2348 PerlLIO_close(p[that]);
2349
4755096e 2350 LOCK_FDPID_MUTEX;
3280af22 2351 sv = *av_fetch(PL_fdpid,p[This],TRUE);
4755096e 2352 UNLOCK_FDPID_MUTEX;
862a34c6 2353 SvUPGRADE(sv,SVt_IV);
45977657 2354 SvIV_set(sv, pid);
3280af22 2355 PL_forkprocess = pid;
e446cec8
IZ
2356 if (did_pipes && pid > 0) {
2357 int errkid;
2358 int n = 0, n1;
2359
2360 while (n < sizeof(int)) {
2361 n1 = PerlLIO_read(pp[0],
2362 (void*)(((char*)&errkid)+n),
2363 (sizeof(int)) - n);
2364 if (n1 <= 0)
2365 break;
2366 n += n1;
2367 }
2f96c702
IZ
2368 PerlLIO_close(pp[0]);
2369 did_pipes = 0;
e446cec8 2370 if (n) { /* Error */
faa466a7 2371 int pid2, status;
8c51524e 2372 PerlLIO_close(p[This]);
e446cec8 2373 if (n != sizeof(int))
cea2e8a9 2374 Perl_croak(aTHX_ "panic: kid popen errno read");
faa466a7
RG
2375 do {
2376 pid2 = wait4pid(pid, &status, 0);
2377 } while (pid2 == -1 && errno == EINTR);
e446cec8
IZ
2378 errno = errkid; /* Propagate errno from kid */
2379 return Nullfp;
2380 }
2381 }
2382 if (did_pipes)
2383 PerlLIO_close(pp[0]);
8ac85365 2384 return PerlIO_fdopen(p[This], mode);
a687059c 2385}
7c0587c8 2386#else
85ca448a 2387#if defined(atarist) || defined(EPOC)
7c0587c8 2388FILE *popen();
760ac839 2389PerlIO *
864dbfa3 2390Perl_my_popen(pTHX_ char *cmd, char *mode)
7c0587c8 2391{
45bc9206 2392 PERL_FLUSHALL_FOR_CHILD;
a1d180c4
NIS
2393 /* Call system's popen() to get a FILE *, then import it.
2394 used 0 for 2nd parameter to PerlIO_importFILE;
2395 apparently not used
2396 */
2397 return PerlIO_importFILE(popen(cmd, mode), 0);
7c0587c8 2398}
2b96b0a5
JH
2399#else
2400#if defined(DJGPP)
2401FILE *djgpp_popen();
2402PerlIO *
2403Perl_my_popen(pTHX_ char *cmd, char *mode)
2404{
2405 PERL_FLUSHALL_FOR_CHILD;
2406 /* Call system's popen() to get a FILE *, then import it.
2407 used 0 for 2nd parameter to PerlIO_importFILE;
2408 apparently not used
2409 */
2410 return PerlIO_importFILE(djgpp_popen(cmd, mode), 0);
2411}
2412#endif
7c0587c8
LW
2413#endif
2414
2415#endif /* !DOSISH */
a687059c 2416
52e18b1f
GS
2417/* this is called in parent before the fork() */
2418void
2419Perl_atfork_lock(void)
2420{
27da23d5 2421 dVAR;
3db8f154 2422#if defined(USE_ITHREADS)
52e18b1f
GS
2423 /* locks must be held in locking order (if any) */
2424# ifdef MYMALLOC
2425 MUTEX_LOCK(&PL_malloc_mutex);
2426# endif
2427 OP_REFCNT_LOCK;
2428#endif
2429}
2430
2431/* this is called in both parent and child after the fork() */
2432void
2433Perl_atfork_unlock(void)
2434{
27da23d5 2435 dVAR;
3db8f154 2436#if defined(USE_ITHREADS)
52e18b1f
GS
2437 /* locks must be released in same order as in atfork_lock() */
2438# ifdef MYMALLOC
2439 MUTEX_UNLOCK(&PL_malloc_mutex);
2440# endif
2441 OP_REFCNT_UNLOCK;
2442#endif
2443}
2444
2445Pid_t
2446Perl_my_fork(void)
2447{
2448#if defined(HAS_FORK)
2449 Pid_t pid;
3db8f154 2450#if defined(USE_ITHREADS) && !defined(HAS_PTHREAD_ATFORK)
52e18b1f
GS
2451 atfork_lock();
2452 pid = fork();
2453 atfork_unlock();
2454#else
2455 /* atfork_lock() and atfork_unlock() are installed as pthread_atfork()
2456 * handlers elsewhere in the code */
2457 pid = fork();
2458#endif
2459 return pid;
2460#else
2461 /* this "canna happen" since nothing should be calling here if !HAS_FORK */
2462 Perl_croak_nocontext("fork() not available");
b961a566 2463 return 0;
52e18b1f
GS
2464#endif /* HAS_FORK */
2465}
2466
748a9306 2467#ifdef DUMP_FDS
35ff7856 2468void
864dbfa3 2469Perl_dump_fds(pTHX_ char *s)
ae986130
LW
2470{
2471 int fd;
c623ac67 2472 Stat_t tmpstatbuf;
ae986130 2473
bf49b057 2474 PerlIO_printf(Perl_debug_log,"%s", s);
ae986130 2475 for (fd = 0; fd < 32; fd++) {
6ad3d225 2476 if (PerlLIO_fstat(fd,&tmpstatbuf) >= 0)
bf49b057 2477 PerlIO_printf(Perl_debug_log," %d",fd);
ae986130 2478 }
bf49b057 2479 PerlIO_printf(Perl_debug_log,"\n");
27da23d5 2480 return;
ae986130 2481}
35ff7856 2482#endif /* DUMP_FDS */
ae986130 2483
fe14fcc3 2484#ifndef HAS_DUP2
fec02dd3 2485int
ba106d47 2486dup2(int oldfd, int newfd)
a687059c 2487{
a0d0e21e 2488#if defined(HAS_FCNTL) && defined(F_DUPFD)
fec02dd3
AD
2489 if (oldfd == newfd)
2490 return oldfd;
6ad3d225 2491 PerlLIO_close(newfd);
fec02dd3 2492 return fcntl(oldfd, F_DUPFD, newfd);
62b28dd9 2493#else
fc36a67e 2494#define DUP2_MAX_FDS 256
2495 int fdtmp[DUP2_MAX_FDS];
79072805 2496 I32 fdx = 0;
ae986130
LW
2497 int fd;
2498
fe14fcc3 2499 if (oldfd == newfd)
fec02dd3 2500 return oldfd;
6ad3d225 2501 PerlLIO_close(newfd);
fc36a67e 2502 /* good enough for low fd's... */
6ad3d225 2503 while ((fd = PerlLIO_dup(oldfd)) != newfd && fd >= 0) {
fc36a67e 2504 if (fdx >= DUP2_MAX_FDS) {
6ad3d225 2505 PerlLIO_close(fd);
fc36a67e 2506 fd = -1;
2507 break;
2508 }
ae986130 2509 fdtmp[fdx++] = fd;
fc36a67e 2510 }
ae986130 2511 while (fdx > 0)
6ad3d225 2512 PerlLIO_close(fdtmp[--fdx]);
fec02dd3 2513 return fd;
62b28dd9 2514#endif
a687059c
LW
2515}
2516#endif
2517
64ca3a65 2518#ifndef PERL_MICRO
ff68c719 2519#ifdef HAS_SIGACTION
2520
abea2c45
HS
2521#ifdef MACOS_TRADITIONAL
2522/* We don't want restart behavior on MacOS */
2523#undef SA_RESTART
2524#endif
2525
ff68c719 2526Sighandler_t
864dbfa3 2527Perl_rsignal(pTHX_ int signo, Sighandler_t handler)
ff68c719 2528{
27da23d5 2529 dVAR;
ff68c719 2530 struct sigaction act, oact;
2531
a10b1e10
JH
2532#ifdef USE_ITHREADS
2533 /* only "parent" interpreter can diddle signals */
2534 if (PL_curinterp != aTHX)
8aad04aa 2535 return (Sighandler_t) SIG_ERR;
a10b1e10
JH
2536#endif
2537
8aad04aa 2538 act.sa_handler = (void(*)(int))handler;
ff68c719 2539 sigemptyset(&act.sa_mask);
2540 act.sa_flags = 0;
2541#ifdef SA_RESTART
4ffa73a3
JH
2542 if (PL_signals & PERL_SIGNALS_UNSAFE_FLAG)
2543 act.sa_flags |= SA_RESTART; /* SVR4, 4.3+BSD */
0a8e0eff 2544#endif
358837b8 2545#if defined(SA_NOCLDWAIT) && !defined(BSDish) /* See [perl #18849] */
8aad04aa 2546 if (signo == SIGCHLD && handler == (Sighandler_t) SIG_IGN)
85264bed
CS
2547 act.sa_flags |= SA_NOCLDWAIT;
2548#endif
ff68c719 2549 if (sigaction(signo, &act, &oact) == -1)
8aad04aa 2550 return (Sighandler_t) SIG_ERR;
ff68c719 2551 else
8aad04aa 2552 return (Sighandler_t) oact.sa_handler;
ff68c719 2553}
2554
2555Sighandler_t
864dbfa3 2556Perl_rsignal_state(pTHX_ int signo)
ff68c719 2557{
2558 struct sigaction oact;
2559
2560 if (sigaction(signo, (struct sigaction *)NULL, &oact) == -1)
8aad04aa 2561 return (Sighandler_t) SIG_ERR;
ff68c719 2562 else
8aad04aa 2563 return (Sighandler_t) oact.sa_handler;
ff68c719 2564}
2565
2566int
864dbfa3 2567Perl_rsignal_save(pTHX_ int signo, Sighandler_t handler, Sigsave_t *save)
ff68c719 2568{
27da23d5 2569 dVAR;
ff68c719 2570 struct sigaction act;
2571
a10b1e10
JH
2572#ifdef USE_ITHREADS
2573 /* only "parent" interpreter can diddle signals */
2574 if (PL_curinterp != aTHX)
2575 return -1;
2576#endif
2577
8aad04aa 2578 act.sa_handler = (void(*)(int))handler;
ff68c719 2579 sigemptyset(&act.sa_mask);
2580 act.sa_flags = 0;
2581#ifdef SA_RESTART
4ffa73a3
JH
2582 if (PL_signals & PERL_SIGNALS_UNSAFE_FLAG)
2583 act.sa_flags |= SA_RESTART; /* SVR4, 4.3+BSD */
0a8e0eff 2584#endif
36b5d377 2585#if defined(SA_NOCLDWAIT) && !defined(BSDish) /* See [perl #18849] */
8aad04aa 2586 if (signo == SIGCHLD && handler == (Sighandler_t) SIG_IGN)
85264bed
CS
2587 act.sa_flags |= SA_NOCLDWAIT;
2588#endif
ff68c719 2589 return sigaction(signo, &act, save);
2590}
2591
2592int
864dbfa3 2593Perl_rsignal_restore(pTHX_ int signo, Sigsave_t *save)
ff68c719 2594{
27da23d5 2595 dVAR;
a10b1e10
JH
2596#ifdef USE_ITHREADS
2597 /* only "parent" interpreter can diddle signals */
2598 if (PL_curinterp != aTHX)
2599 return -1;
2600#endif
2601
ff68c719 2602 return sigaction(signo, save, (struct sigaction *)NULL);
2603}
2604
2605#else /* !HAS_SIGACTION */
2606
2607Sighandler_t
864dbfa3 2608Perl_rsignal(pTHX_ int signo, Sighandler_t handler)
ff68c719 2609{
39f1703b 2610#if defined(USE_ITHREADS) && !defined(WIN32)
a10b1e10
JH
2611 /* only "parent" interpreter can diddle signals */
2612 if (PL_curinterp != aTHX)
8aad04aa 2613 return (Sighandler_t) SIG_ERR;
a10b1e10
JH
2614#endif
2615
6ad3d225 2616 return PerlProc_signal(signo, handler);
ff68c719 2617}
2618
fabdb6c0 2619static Signal_t
4e35701f 2620sig_trap(int signo)
ff68c719 2621{
27da23d5
JH
2622 dVAR;
2623 PL_sig_trapped++;
ff68c719 2624}
2625
2626Sighandler_t
864dbfa3 2627Perl_rsignal_state(pTHX_ int signo)
ff68c719 2628{
27da23d5 2629 dVAR;
ff68c719 2630 Sighandler_t oldsig;
2631
39f1703b 2632#if defined(USE_ITHREADS) && !defined(WIN32)
a10b1e10
JH
2633 /* only "parent" interpreter can diddle signals */
2634 if (PL_curinterp != aTHX)
8aad04aa 2635 return (Sighandler_t) SIG_ERR;
a10b1e10
JH
2636#endif
2637
27da23d5 2638 PL_sig_trapped = 0;
6ad3d225
GS
2639 oldsig = PerlProc_signal(signo, sig_trap);
2640 PerlProc_signal(signo, oldsig);
27da23d5 2641 if (PL_sig_trapped)
3aed30dc 2642 PerlProc_kill(PerlProc_getpid(), signo);
ff68c719 2643 return oldsig;
2644}
2645
2646int
864dbfa3 2647Perl_rsignal_save(pTHX_ int signo, Sighandler_t handler, Sigsave_t *save)
ff68c719 2648{
39f1703b 2649#if defined(USE_ITHREADS) && !defined(WIN32)
a10b1e10
JH
2650 /* only "parent" interpreter can diddle signals */
2651 if (PL_curinterp != aTHX)
2652 return -1;
2653#endif
6ad3d225 2654 *save = PerlProc_signal(signo, handler);
8aad04aa 2655 return (*save == (Sighandler_t) SIG_ERR) ? -1 : 0;
ff68c719 2656}
2657
2658int
864dbfa3 2659Perl_rsignal_restore(pTHX_ int signo, Sigsave_t *save)
ff68c719 2660{
39f1703b 2661#if defined(USE_ITHREADS) && !defined(WIN32)
a10b1e10
JH
2662 /* only "parent" interpreter can diddle signals */
2663 if (PL_curinterp != aTHX)
2664 return -1;
2665#endif
8aad04aa 2666 return (PerlProc_signal(signo, *save) == (Sighandler_t) SIG_ERR) ? -1 : 0;
ff68c719 2667}
2668
2669#endif /* !HAS_SIGACTION */
64ca3a65 2670#endif /* !PERL_MICRO */
ff68c719 2671
5f05dabc 2672 /* VMS' my_pclose() is in VMS.c; same with OS/2 */
cd39f2b6 2673#if (!defined(DOSISH) || defined(HAS_FORK) || defined(AMIGAOS)) && !defined(VMS) && !defined(__OPEN_VM) && !defined(EPOC) && !defined(MACOS_TRADITIONAL)
79072805 2674I32
864dbfa3 2675Perl_my_pclose(pTHX_ PerlIO *ptr)
a687059c 2676{
97aff369 2677 dVAR;
ff68c719 2678 Sigsave_t hstat, istat, qstat;
a687059c 2679 int status;
a0d0e21e 2680 SV **svp;
d8a83dd3
JH
2681 Pid_t pid;
2682 Pid_t pid2;
03136e13 2683 bool close_failed;
b7953727 2684 int saved_errno = 0;
22fae026
TM
2685#ifdef WIN32
2686 int saved_win32_errno;
2687#endif
a687059c 2688
4755096e 2689 LOCK_FDPID_MUTEX;
3280af22 2690 svp = av_fetch(PL_fdpid,PerlIO_fileno(ptr),TRUE);
4755096e 2691 UNLOCK_FDPID_MUTEX;
25d92023 2692 pid = (SvTYPE(*svp) == SVt_IV) ? SvIVX(*svp) : -1;
a0d0e21e 2693 SvREFCNT_dec(*svp);
3280af22 2694 *svp = &PL_sv_undef;
ddcf38b7
IZ
2695#ifdef OS2
2696 if (pid == -1) { /* Opened by popen. */
2697 return my_syspclose(ptr);
2698 }
a1d180c4 2699#endif
03136e13
CS
2700 if ((close_failed = (PerlIO_close(ptr) == EOF))) {
2701 saved_errno = errno;
22fae026
TM
2702#ifdef WIN32
2703 saved_win32_errno = GetLastError();
2704#endif
03136e13 2705 }
7c0587c8 2706#ifdef UTS
6ad3d225 2707 if(PerlProc_kill(pid, 0) < 0) { return(pid); } /* HOM 12/23/91 */
7c0587c8 2708#endif
64ca3a65 2709#ifndef PERL_MICRO
8aad04aa
JH
2710 rsignal_save(SIGHUP, (Sighandler_t) SIG_IGN, &hstat);
2711 rsignal_save(SIGINT, (Sighandler_t) SIG_IGN, &istat);
2712 rsignal_save(SIGQUIT, (Sighandler_t) SIG_IGN, &qstat);
64ca3a65 2713#endif
748a9306 2714 do {
1d3434b8
GS
2715 pid2 = wait4pid(pid, &status, 0);
2716 } while (pid2 == -1 && errno == EINTR);
64ca3a65 2717#ifndef PERL_MICRO
ff68c719 2718 rsignal_restore(SIGHUP, &hstat);
2719 rsignal_restore(SIGINT, &istat);
2720 rsignal_restore(SIGQUIT, &qstat);
64ca3a65 2721#endif
03136e13 2722 if (close_failed) {
ce6e1103 2723 SETERRNO(saved_errno, 0);
03136e13
CS
2724 return -1;
2725 }
1d3434b8 2726 return(pid2 < 0 ? pid2 : status == 0 ? 0 : (errno = 0, status));
20188a90 2727}
4633a7c4
LW
2728#endif /* !DOSISH */
2729
2986a63f 2730#if (!defined(DOSISH) || defined(OS2) || defined(WIN32) || defined(NETWARE)) && !defined(MACOS_TRADITIONAL)
79072805 2731I32
d8a83dd3 2732Perl_wait4pid(pTHX_ Pid_t pid, int *statusp, int flags)
20188a90 2733{
97aff369 2734 dVAR;
27da23d5 2735 I32 result = 0;
b7953727
JH
2736 if (!pid)
2737 return -1;
ca0c25f6 2738#ifdef PERL_USES_PL_PIDSTATUS
b7953727 2739 {
3aed30dc 2740 if (pid > 0) {
12072db5
NC
2741 /* The keys in PL_pidstatus are now the raw 4 (or 8) bytes of the
2742 pid, rather than a string form. */
c4420975 2743 SV * const * const svp = hv_fetch(PL_pidstatus,(const char*) &pid,sizeof(Pid_t),FALSE);
3aed30dc
HS
2744 if (svp && *svp != &PL_sv_undef) {
2745 *statusp = SvIVX(*svp);
12072db5
NC
2746 (void)hv_delete(PL_pidstatus,(const char*) &pid,sizeof(Pid_t),
2747 G_DISCARD);
3aed30dc
HS
2748 return pid;
2749 }
2750 }
2751 else {
2752 HE *entry;
2753
2754 hv_iterinit(PL_pidstatus);
2755 if ((entry = hv_iternext(PL_pidstatus))) {
c4420975 2756 SV * const sv = hv_iterval(PL_pidstatus,entry);
7ea75b61 2757 I32 len;
0bcc34c2 2758 const char * const spid = hv_iterkey(entry,&len);
27da23d5 2759
12072db5
NC
2760 assert (len == sizeof(Pid_t));
2761 memcpy((char *)&pid, spid, len);
3aed30dc 2762 *statusp = SvIVX(sv);
7b9a3241
NC
2763 /* The hash iterator is currently on this entry, so simply
2764 calling hv_delete would trigger the lazy delete, which on
2765 aggregate does more work, beacuse next call to hv_iterinit()
2766 would spot the flag, and have to call the delete routine,
2767 while in the meantime any new entries can't re-use that
2768 memory. */
2769 hv_iterinit(PL_pidstatus);
7ea75b61 2770 (void)hv_delete(PL_pidstatus,spid,len,G_DISCARD);
3aed30dc
HS
2771 return pid;
2772 }
20188a90
LW
2773 }
2774 }
68a29c53 2775#endif
79072805 2776#ifdef HAS_WAITPID
367f3c24
IZ
2777# ifdef HAS_WAITPID_RUNTIME
2778 if (!HAS_WAITPID_RUNTIME)
2779 goto hard_way;
2780# endif
cddd4526 2781 result = PerlProc_waitpid(pid,statusp,flags);
dfcfdb64 2782 goto finish;
367f3c24
IZ
2783#endif
2784#if !defined(HAS_WAITPID) && defined(HAS_WAIT4)
cddd4526 2785 result = wait4((pid==-1)?0:pid,statusp,flags,Null(struct rusage *));
dfcfdb64 2786 goto finish;
367f3c24 2787#endif
ca0c25f6 2788#ifdef PERL_USES_PL_PIDSTATUS
27da23d5 2789#if defined(HAS_WAITPID) && defined(HAS_WAITPID_RUNTIME)
367f3c24 2790 hard_way:
27da23d5 2791#endif
a0d0e21e 2792 {
a0d0e21e 2793 if (flags)
cea2e8a9 2794 Perl_croak(aTHX_ "Can't do waitpid with flags");
a0d0e21e 2795 else {
76e3520e 2796 while ((result = PerlProc_wait(statusp)) != pid && pid > 0 && result >= 0)
a0d0e21e
LW
2797 pidgone(result,*statusp);
2798 if (result < 0)
2799 *statusp = -1;
2800 }
a687059c
LW
2801 }
2802#endif
27da23d5 2803#if defined(HAS_WAITPID) || defined(HAS_WAIT4)
dfcfdb64 2804 finish:
27da23d5 2805#endif
cddd4526
NIS
2806 if (result < 0 && errno == EINTR) {
2807 PERL_ASYNC_CHECK();
2808 }
2809 return result;
a687059c 2810}
2986a63f 2811#endif /* !DOSISH || OS2 || WIN32 || NETWARE */
a687059c 2812
ca0c25f6 2813#ifdef PERL_USES_PL_PIDSTATUS
7c0587c8 2814void
d8a83dd3 2815Perl_pidgone(pTHX_ Pid_t pid, int status)
a687059c 2816{
79072805 2817 register SV *sv;
a687059c 2818
12072db5 2819 sv = *hv_fetch(PL_pidstatus,(const char*)&pid,sizeof(Pid_t),TRUE);
862a34c6 2820 SvUPGRADE(sv,SVt_IV);
45977657 2821 SvIV_set(sv, status);
20188a90 2822 return;
a687059c 2823}
ca0c25f6 2824#endif
a687059c 2825
85ca448a 2826#if defined(atarist) || defined(OS2) || defined(EPOC)
7c0587c8 2827int pclose();
ddcf38b7
IZ
2828#ifdef HAS_FORK
2829int /* Cannot prototype with I32
2830 in os2ish.h. */
ba106d47 2831my_syspclose(PerlIO *ptr)
ddcf38b7 2832#else
79072805 2833I32
864dbfa3 2834Perl_my_pclose(pTHX_ PerlIO *ptr)
a1d180c4 2835#endif
a687059c 2836{
760ac839 2837 /* Needs work for PerlIO ! */
c4420975 2838 FILE * const f = PerlIO_findFILE(ptr);
7452cf6a 2839 const I32 result = pclose(f);
2b96b0a5
JH
2840 PerlIO_releaseFILE(ptr,f);
2841 return result;
2842}
2843#endif
2844
933fea7f 2845#if defined(DJGPP)
2b96b0a5
JH
2846int djgpp_pclose();
2847I32
2848Perl_my_pclose(pTHX_ PerlIO *ptr)
2849{
2850 /* Needs work for PerlIO ! */
c4420975 2851 FILE * const f = PerlIO_findFILE(ptr);
2b96b0a5 2852 I32 result = djgpp_pclose(f);
933fea7f 2853 result = (result << 8) & 0xff00;
760ac839
LW
2854 PerlIO_releaseFILE(ptr,f);
2855 return result;
a687059c 2856}
7c0587c8 2857#endif
9f68db38
LW
2858
2859void
864dbfa3 2860Perl_repeatcpy(pTHX_ register char *to, register const char *from, I32 len, register I32 count)
9f68db38 2861{
79072805 2862 register I32 todo;
c4420975 2863 register const char * const frombase = from;
9f68db38
LW
2864
2865 if (len == 1) {
08105a92 2866 register const char c = *from;
9f68db38 2867 while (count-- > 0)
5926133d 2868 *to++ = c;
9f68db38
LW
2869 return;
2870 }
2871 while (count-- > 0) {
2872 for (todo = len; todo > 0; todo--) {
2873 *to++ = *from++;
2874 }
2875 from = frombase;
2876 }
2877}
0f85fab0 2878
fe14fcc3 2879#ifndef HAS_RENAME
79072805 2880I32
4373e329 2881Perl_same_dirent(pTHX_ const char *a, const char *b)
62b28dd9 2882{
93a17b20
LW
2883 char *fa = strrchr(a,'/');
2884 char *fb = strrchr(b,'/');
c623ac67
GS
2885 Stat_t tmpstatbuf1;
2886 Stat_t tmpstatbuf2;
c4420975 2887 SV * const tmpsv = sv_newmortal();
62b28dd9
LW
2888
2889 if (fa)
2890 fa++;
2891 else
2892 fa = a;
2893 if (fb)
2894 fb++;
2895 else
2896 fb = b;
2897 if (strNE(a,b))
2898 return FALSE;
2899 if (fa == a)
616d8c9c 2900 sv_setpvn(tmpsv, ".", 1);
62b28dd9 2901 else
46fc3d4c 2902 sv_setpvn(tmpsv, a, fa - a);
95a20fc0 2903 if (PerlLIO_stat(SvPVX_const(tmpsv), &tmpstatbuf1) < 0)
62b28dd9
LW
2904 return FALSE;
2905 if (fb == b)
616d8c9c 2906 sv_setpvn(tmpsv, ".", 1);
62b28dd9 2907 else
46fc3d4c 2908 sv_setpvn(tmpsv, b, fb - b);
95a20fc0 2909 if (PerlLIO_stat(SvPVX_const(tmpsv), &tmpstatbuf2) < 0)
62b28dd9
LW
2910 return FALSE;
2911 return tmpstatbuf1.st_dev == tmpstatbuf2.st_dev &&
2912 tmpstatbuf1.st_ino == tmpstatbuf2.st_ino;
2913}
fe14fcc3
LW
2914#endif /* !HAS_RENAME */
2915
491527d0 2916char*
7f315aed
NC
2917Perl_find_script(pTHX_ const char *scriptname, bool dosearch,
2918 const char *const *const search_ext, I32 flags)
491527d0 2919{
97aff369 2920 dVAR;
bd61b366
SS
2921 const char *xfound = NULL;
2922 char *xfailed = NULL;
0f31cffe 2923 char tmpbuf[MAXPATHLEN];
491527d0 2924 register char *s;
5f74f29c 2925 I32 len = 0;
491527d0
GS
2926 int retval;
2927#if defined(DOSISH) && !defined(OS2) && !defined(atarist)
2928# define SEARCH_EXTS ".bat", ".cmd", NULL
2929# define MAX_EXT_LEN 4
2930#endif
2931#ifdef OS2
2932# define SEARCH_EXTS ".cmd", ".btm", ".bat", ".pl", NULL
2933# define MAX_EXT_LEN 4
2934#endif
2935#ifdef VMS
2936# define SEARCH_EXTS ".pl", ".com", NULL
2937# define MAX_EXT_LEN 4
2938#endif
2939 /* additional extensions to try in each dir if scriptname not found */
2940#ifdef SEARCH_EXTS
0bcc34c2 2941 static const char *const exts[] = { SEARCH_EXTS };
7f315aed 2942 const char *const *const ext = search_ext ? search_ext : exts;
491527d0 2943 int extidx = 0, i = 0;
bd61b366 2944 const char *curext = NULL;
491527d0 2945#else
53c1dcc0 2946 PERL_UNUSED_ARG(search_ext);
491527d0
GS
2947# define MAX_EXT_LEN 0
2948#endif
2949
2950 /*
2951 * If dosearch is true and if scriptname does not contain path
2952 * delimiters, search the PATH for scriptname.
2953 *
2954 * If SEARCH_EXTS is also defined, will look for each
2955 * scriptname{SEARCH_EXTS} whenever scriptname is not found
2956 * while searching the PATH.
2957 *
2958 * Assuming SEARCH_EXTS is C<".foo",".bar",NULL>, PATH search
2959 * proceeds as follows:
2960 * If DOSISH or VMSISH:
2961 * + look for ./scriptname{,.foo,.bar}
2962 * + search the PATH for scriptname{,.foo,.bar}
2963 *
2964 * If !DOSISH:
2965 * + look *only* in the PATH for scriptname{,.foo,.bar} (note
2966 * this will not look in '.' if it's not in the PATH)
2967 */
84486fc6 2968 tmpbuf[0] = '\0';
491527d0
GS
2969
2970#ifdef VMS
2971# ifdef ALWAYS_DEFTYPES
2972 len = strlen(scriptname);
2973 if (!(len == 1 && *scriptname == '-') && scriptname[len-1] != ':') {
c4420975 2974 int idx = 0, deftypes = 1;
491527d0
GS
2975 bool seen_dot = 1;
2976
bd61b366 2977 const int hasdir = !dosearch || (strpbrk(scriptname,":[</") != NULL);
491527d0
GS
2978# else
2979 if (dosearch) {
c4420975 2980 int idx = 0, deftypes = 1;
491527d0
GS
2981 bool seen_dot = 1;
2982
bd61b366 2983 const int hasdir = (strpbrk(scriptname,":[</") != NULL);
491527d0
GS
2984# endif
2985 /* The first time through, just add SEARCH_EXTS to whatever we
2986 * already have, so we can check for default file types. */
2987 while (deftypes ||
84486fc6 2988 (!hasdir && my_trnlnm("DCL$PATH",tmpbuf,idx++)) )
491527d0
GS
2989 {
2990 if (deftypes) {
2991 deftypes = 0;
84486fc6 2992 *tmpbuf = '\0';
491527d0 2993 }
84486fc6
GS
2994 if ((strlen(tmpbuf) + strlen(scriptname)
2995 + MAX_EXT_LEN) >= sizeof tmpbuf)
491527d0 2996 continue; /* don't search dir with too-long name */
84486fc6 2997 strcat(tmpbuf, scriptname);
491527d0
GS
2998#else /* !VMS */
2999
3000#ifdef DOSISH
3001 if (strEQ(scriptname, "-"))
3002 dosearch = 0;
3003 if (dosearch) { /* Look in '.' first. */
fe2774ed 3004 const char *cur = scriptname;
491527d0
GS
3005#ifdef SEARCH_EXTS
3006 if ((curext = strrchr(scriptname,'.'))) /* possible current ext */
3007 while (ext[i])
3008 if (strEQ(ext[i++],curext)) {
3009 extidx = -1; /* already has an ext */
3010 break;
3011 }
3012 do {
3013#endif
3014 DEBUG_p(PerlIO_printf(Perl_debug_log,
3015 "Looking for %s\n",cur));
017f25f1
IZ
3016 if (PerlLIO_stat(cur,&PL_statbuf) >= 0
3017 && !S_ISDIR(PL_statbuf.st_mode)) {
491527d0
GS
3018 dosearch = 0;
3019 scriptname = cur;
3020#ifdef SEARCH_EXTS
3021 break;
3022#endif
3023 }
3024#ifdef SEARCH_EXTS
3025 if (cur == scriptname) {
3026 len = strlen(scriptname);
84486fc6 3027 if (len+MAX_EXT_LEN+1 >= sizeof(tmpbuf))
491527d0 3028 break;
490a0e98 3029 /* FIXME? Convert to memcpy */
84486fc6 3030 cur = strcpy(tmpbuf, scriptname);
491527d0
GS
3031 }
3032 } while (extidx >= 0 && ext[extidx] /* try an extension? */
84486fc6 3033 && strcpy(tmpbuf+len, ext[extidx++]));
491527d0
GS
3034#endif
3035 }
3036#endif
3037
cd39f2b6
JH
3038#ifdef MACOS_TRADITIONAL
3039 if (dosearch && !strchr(scriptname, ':') &&
3040 (s = PerlEnv_getenv("Commands")))
3041#else
491527d0
GS
3042 if (dosearch && !strchr(scriptname, '/')
3043#ifdef DOSISH
3044 && !strchr(scriptname, '\\')
3045#endif
cd39f2b6
JH
3046 && (s = PerlEnv_getenv("PATH")))
3047#endif
3048 {
491527d0 3049 bool seen_dot = 0;
92f0c265 3050
3280af22
NIS
3051 PL_bufend = s + strlen(s);
3052 while (s < PL_bufend) {
cd39f2b6
JH
3053#ifdef MACOS_TRADITIONAL
3054 s = delimcpy(tmpbuf, tmpbuf + sizeof tmpbuf, s, PL_bufend,
3055 ',',
3056 &len);
3057#else
491527d0
GS
3058#if defined(atarist) || defined(DOSISH)
3059 for (len = 0; *s
3060# ifdef atarist
3061 && *s != ','
3062# endif
3063 && *s != ';'; len++, s++) {
84486fc6
GS
3064 if (len < sizeof tmpbuf)
3065 tmpbuf[len] = *s;
491527d0 3066 }
84486fc6
GS
3067 if (len < sizeof tmpbuf)
3068 tmpbuf[len] = '\0';
491527d0 3069#else /* ! (atarist || DOSISH) */
3280af22 3070 s = delimcpy(tmpbuf, tmpbuf + sizeof tmpbuf, s, PL_bufend,
491527d0
GS
3071 ':',
3072 &len);
3073#endif /* ! (atarist || DOSISH) */
cd39f2b6 3074#endif /* MACOS_TRADITIONAL */
3280af22 3075 if (s < PL_bufend)
491527d0 3076 s++;
84486fc6 3077 if (len + 1 + strlen(scriptname) + MAX_EXT_LEN >= sizeof tmpbuf)
491527d0 3078 continue; /* don't search dir with too-long name */
cd39f2b6
JH
3079#ifdef MACOS_TRADITIONAL
3080 if (len && tmpbuf[len - 1] != ':')
3081 tmpbuf[len++] = ':';
3082#else
491527d0 3083 if (len
490a0e98 3084# if defined(atarist) || defined(__MINT__) || defined(DOSISH)
84486fc6
GS
3085 && tmpbuf[len - 1] != '/'
3086 && tmpbuf[len - 1] != '\\'
490a0e98 3087# endif
491527d0 3088 )
84486fc6
GS
3089 tmpbuf[len++] = '/';
3090 if (len == 2 && tmpbuf[0] == '.')
491527d0 3091 seen_dot = 1;
cd39f2b6 3092#endif
490a0e98
NC
3093 /* FIXME? Convert to memcpy by storing previous strlen(scriptname)
3094 */
84486fc6 3095 (void)strcpy(tmpbuf + len, scriptname);
491527d0
GS
3096#endif /* !VMS */
3097
3098#ifdef SEARCH_EXTS
84486fc6 3099 len = strlen(tmpbuf);
491527d0
GS
3100 if (extidx > 0) /* reset after previous loop */
3101 extidx = 0;
3102 do {
3103#endif
84486fc6 3104 DEBUG_p(PerlIO_printf(Perl_debug_log, "Looking for %s\n",tmpbuf));
3280af22 3105 retval = PerlLIO_stat(tmpbuf,&PL_statbuf);
017f25f1
IZ
3106 if (S_ISDIR(PL_statbuf.st_mode)) {
3107 retval = -1;
3108 }
491527d0
GS
3109#ifdef SEARCH_EXTS
3110 } while ( retval < 0 /* not there */
3111 && extidx>=0 && ext[extidx] /* try an extension? */
84486fc6 3112 && strcpy(tmpbuf+len, ext[extidx++])
491527d0
GS
3113 );
3114#endif
3115 if (retval < 0)
3116 continue;
3280af22
NIS
3117 if (S_ISREG(PL_statbuf.st_mode)
3118 && cando(S_IRUSR,TRUE,&PL_statbuf)
73811745 3119#if !defined(DOSISH) && !defined(MACOS_TRADITIONAL)
3280af22 3120 && cando(S_IXUSR,TRUE,&PL_statbuf)
491527d0
GS
3121#endif
3122 )
3123 {
3aed30dc 3124 xfound = tmpbuf; /* bingo! */
491527d0
GS
3125 break;
3126 }
3127 if (!xfailed)
84486fc6 3128 xfailed = savepv(tmpbuf);
491527d0
GS
3129 }
3130#ifndef DOSISH
017f25f1 3131 if (!xfound && !seen_dot && !xfailed &&
a1d180c4 3132 (PerlLIO_stat(scriptname,&PL_statbuf) < 0
017f25f1 3133 || S_ISDIR(PL_statbuf.st_mode)))
491527d0
GS
3134#endif
3135 seen_dot = 1; /* Disable message. */
9ccb31f9
GS
3136 if (!xfound) {
3137 if (flags & 1) { /* do or die? */
3aed30dc 3138 Perl_croak(aTHX_ "Can't %s %s%s%s",
9ccb31f9
GS
3139 (xfailed ? "execute" : "find"),
3140 (xfailed ? xfailed : scriptname),
3141 (xfailed ? "" : " on PATH"),
3142 (xfailed || seen_dot) ? "" : ", '.' not in PATH");
3143 }
bd61b366 3144 scriptname = NULL;
9ccb31f9 3145 }
43c5f42d 3146 Safefree(xfailed);
491527d0
GS
3147 scriptname = xfound;
3148 }
bd61b366 3149 return (scriptname ? savepv(scriptname) : NULL);
491527d0
GS
3150}
3151
ba869deb
GS
3152#ifndef PERL_GET_CONTEXT_DEFINED
3153
3154void *
3155Perl_get_context(void)
3156{
27da23d5 3157 dVAR;
3db8f154 3158#if defined(USE_ITHREADS)
ba869deb
GS
3159# ifdef OLD_PTHREADS_API
3160 pthread_addr_t t;
3161 if (pthread_getspecific(PL_thr_key, &t))
3162 Perl_croak_nocontext("panic: pthread_getspecific");
3163 return (void*)t;
3164# else
bce813aa 3165# ifdef I_MACH_CTHREADS
8b8b35ab 3166 return (void*)cthread_data(cthread_self());
bce813aa 3167# else
8b8b35ab
JH
3168 return (void*)PTHREAD_GETSPECIFIC(PL_thr_key);
3169# endif
c44d3fdb 3170# endif
ba869deb
GS
3171#else
3172 return (void*)NULL;
3173#endif
3174}
3175
3176void
3177Perl_set_context(void *t)
3178{
8772537c 3179 dVAR;
3db8f154 3180#if defined(USE_ITHREADS)
c44d3fdb
GS
3181# ifdef I_MACH_CTHREADS
3182 cthread_set_data(cthread_self(), t);
3183# else
ba869deb
GS
3184 if (pthread_setspecific(PL_thr_key, t))
3185 Perl_croak_nocontext("panic: pthread_setspecific");
c44d3fdb 3186# endif
b464bac0 3187#else
8772537c 3188 PERL_UNUSED_ARG(t);
ba869deb
GS
3189#endif
3190}
3191
3192#endif /* !PERL_GET_CONTEXT_DEFINED */
491527d0 3193
27da23d5 3194#if defined(PERL_GLOBAL_STRUCT) && !defined(PERL_GLOBAL_STRUCT_PRIVATE)
22239a37 3195struct perl_vars *
864dbfa3 3196Perl_GetVars(pTHX)
22239a37 3197{
533c011a 3198 return &PL_Vars;
22239a37 3199}
31fb1209
NIS
3200#endif
3201
1cb0ed9b 3202char **
864dbfa3 3203Perl_get_op_names(pTHX)
31fb1209 3204{
27da23d5 3205 return (char **)PL_op_name;
31fb1209
NIS
3206}
3207
1cb0ed9b 3208char **
864dbfa3 3209Perl_get_op_descs(pTHX)
31fb1209 3210{
27da23d5 3211 return (char **)PL_op_desc;
31fb1209 3212}
9e6b2b00 3213
e1ec3a88 3214const char *
864dbfa3 3215Perl_get_no_modify(pTHX)
9e6b2b00 3216{
e1ec3a88 3217 return PL_no_modify;
9e6b2b00
GS
3218}
3219
3220U32 *
864dbfa3 3221Perl_get_opargs(pTHX)
9e6b2b00 3222{
27da23d5 3223 return (U32 *)PL_opargs;
9e6b2b00 3224}
51aa15f3 3225
0cb96387
GS
3226PPADDR_t*
3227Perl_get_ppaddr(pTHX)
3228{
27da23d5 3229 dVAR;
12ae5dfc 3230 return (PPADDR_t*)PL_ppaddr;
0cb96387
GS
3231}
3232
a6c40364
GS
3233#ifndef HAS_GETENV_LEN
3234char *
bf4acbe4 3235Perl_getenv_len(pTHX_ const char *env_elem, unsigned long *len)
a6c40364 3236{
8772537c 3237 char * const env_trans = PerlEnv_getenv(env_elem);
a6c40364
GS
3238 if (env_trans)
3239 *len = strlen(env_trans);
3240 return env_trans;
f675dbe5
CB
3241}
3242#endif
3243
dc9e4912
GS
3244
3245MGVTBL*
864dbfa3 3246Perl_get_vtbl(pTHX_ int vtbl_id)
dc9e4912 3247{
7452cf6a 3248 const MGVTBL* result;
dc9e4912
GS
3249
3250 switch(vtbl_id) {
3251 case want_vtbl_sv:
3252 result = &PL_vtbl_sv;
3253 break;
3254 case want_vtbl_env:
3255 result = &PL_vtbl_env;
3256 break;
3257 case want_vtbl_envelem:
3258 result = &PL_vtbl_envelem;
3259 break;
3260 case want_vtbl_sig:
3261 result = &PL_vtbl_sig;
3262 break;
3263 case want_vtbl_sigelem:
3264 result = &PL_vtbl_sigelem;
3265 break;
3266 case want_vtbl_pack:
3267 result = &PL_vtbl_pack;
3268 break;
3269 case want_vtbl_packelem:
3270 result = &PL_vtbl_packelem;
3271 break;
3272 case want_vtbl_dbline:
3273 result = &PL_vtbl_dbline;
3274 break;
3275 case want_vtbl_isa:
3276 result = &PL_vtbl_isa;
3277 break;
3278 case want_vtbl_isaelem:
3279 result = &PL_vtbl_isaelem;
3280 break;
3281 case want_vtbl_arylen:
3282 result = &PL_vtbl_arylen;
3283 break;
3284 case want_vtbl_glob:
3285 result = &PL_vtbl_glob;
3286 break;
3287 case want_vtbl_mglob:
3288 result = &PL_vtbl_mglob;
3289 break;
3290 case want_vtbl_nkeys:
3291 result = &PL_vtbl_nkeys;
3292 break;
3293 case want_vtbl_taint:
3294 result = &PL_vtbl_taint;
3295 break;
3296 case want_vtbl_substr:
3297 result = &PL_vtbl_substr;
3298 break;
3299 case want_vtbl_vec:
3300 result = &PL_vtbl_vec;
3301 break;
3302 case want_vtbl_pos:
3303 result = &PL_vtbl_pos;
3304 break;
3305 case want_vtbl_bm:
3306 result = &PL_vtbl_bm;
3307 break;
3308 case want_vtbl_fm:
3309 result = &PL_vtbl_fm;
3310 break;
3311 case want_vtbl_uvar:
3312 result = &PL_vtbl_uvar;
3313 break;
dc9e4912
GS
3314 case want_vtbl_defelem:
3315 result = &PL_vtbl_defelem;
3316 break;
3317 case want_vtbl_regexp:
3318 result = &PL_vtbl_regexp;
3319 break;
3320 case want_vtbl_regdata:
3321 result = &PL_vtbl_regdata;
3322 break;
3323 case want_vtbl_regdatum:
3324 result = &PL_vtbl_regdatum;
3325 break;
3c90161d 3326#ifdef USE_LOCALE_COLLATE
dc9e4912
GS
3327 case want_vtbl_collxfrm:
3328 result = &PL_vtbl_collxfrm;
3329 break;
3c90161d 3330#endif
dc9e4912
GS
3331 case want_vtbl_amagic:
3332 result = &PL_vtbl_amagic;
3333 break;
3334 case want_vtbl_amagicelem:
3335 result = &PL_vtbl_amagicelem;
3336 break;
810b8aa5
GS
3337 case want_vtbl_backref:
3338 result = &PL_vtbl_backref;
3339 break;
7e8c5dac
HS
3340 case want_vtbl_utf8:
3341 result = &PL_vtbl_utf8;
3342 break;
7452cf6a
AL
3343 default:
3344 result = Null(MGVTBL*);
3345 break;
dc9e4912 3346 }
27da23d5 3347 return (MGVTBL*)result;
dc9e4912
GS
3348}
3349
767df6a1 3350I32
864dbfa3 3351Perl_my_fflush_all(pTHX)
767df6a1 3352{
f800e14d 3353#if defined(USE_PERLIO) || defined(FFLUSH_NULL) || defined(USE_SFIO)
ce720889 3354 return PerlIO_flush(NULL);
767df6a1 3355#else
8fbdfb7c 3356# if defined(HAS__FWALK)
f13a2bc0 3357 extern int fflush(FILE *);
74cac757
JH
3358 /* undocumented, unprototyped, but very useful BSDism */
3359 extern void _fwalk(int (*)(FILE *));
8fbdfb7c 3360 _fwalk(&fflush);
74cac757 3361 return 0;
8fa7f367 3362# else
8fbdfb7c 3363# if defined(FFLUSH_ALL) && defined(HAS_STDIO_STREAM_ARRAY)
8fa7f367 3364 long open_max = -1;
8fbdfb7c 3365# ifdef PERL_FFLUSH_ALL_FOPEN_MAX
d2201af2 3366 open_max = PERL_FFLUSH_ALL_FOPEN_MAX;
8fbdfb7c 3367# else
8fa7f367 3368# if defined(HAS_SYSCONF) && defined(_SC_OPEN_MAX)
767df6a1 3369 open_max = sysconf(_SC_OPEN_MAX);
8fa7f367
JH
3370# else
3371# ifdef FOPEN_MAX
74cac757 3372 open_max = FOPEN_MAX;
8fa7f367
JH
3373# else
3374# ifdef OPEN_MAX
74cac757 3375 open_max = OPEN_MAX;
8fa7f367
JH
3376# else
3377# ifdef _NFILE
d2201af2 3378 open_max = _NFILE;
8fa7f367
JH
3379# endif
3380# endif
74cac757 3381# endif
767df6a1
JH
3382# endif
3383# endif
767df6a1
JH
3384 if (open_max > 0) {
3385 long i;
3386 for (i = 0; i < open_max; i++)
d2201af2
AD
3387 if (STDIO_STREAM_ARRAY[i]._file >= 0 &&
3388 STDIO_STREAM_ARRAY[i]._file < open_max &&
3389 STDIO_STREAM_ARRAY[i]._flag)
3390 PerlIO_flush(&STDIO_STREAM_ARRAY[i]);
767df6a1
JH
3391 return 0;
3392 }
8fbdfb7c 3393# endif
93189314 3394 SETERRNO(EBADF,RMS_IFI);
767df6a1 3395 return EOF;
74cac757 3396# endif
767df6a1
JH
3397#endif
3398}
097ee67d 3399
69282e91 3400void
e1ec3a88 3401Perl_report_evil_fh(pTHX_ const GV *gv, const IO *io, I32 op)
bc37a18f 3402{
b64e5050 3403 const char * const func =
66fc2fa5
JH
3404 op == OP_READLINE ? "readline" : /* "<HANDLE>" not nice */
3405 op == OP_LEAVEWRITE ? "write" : /* "write exit" not nice */
bc37a18f 3406 PL_op_desc[op];
b64e5050
AL
3407 const char * const pars = OP_IS_FILETEST(op) ? "" : "()";
3408 const char * const type = OP_IS_SOCKET(op)
3aed30dc
HS
3409 || (gv && io && IoTYPE(io) == IoTYPE_SOCKET)
3410 ? "socket" : "filehandle";
b64e5050 3411 const char * const name = gv && isGV(gv) ? GvENAME(gv) : NULL;
66fc2fa5 3412
4c80c0b2 3413 if (op == OP_phoney_OUTPUT_ONLY || op == OP_phoney_INPUT_ONLY) {
3aed30dc 3414 if (ckWARN(WARN_IO)) {
b64e5050 3415 const char * const direction = (op == OP_phoney_INPUT_ONLY) ? "in" : "out";
3aed30dc
HS
3416 if (name && *name)
3417 Perl_warner(aTHX_ packWARN(WARN_IO),
3418 "Filehandle %s opened only for %sput",
fd322ea4 3419 name, direction);
3aed30dc
HS
3420 else
3421 Perl_warner(aTHX_ packWARN(WARN_IO),
fd322ea4 3422 "Filehandle opened only for %sput", direction);
3aed30dc 3423 }
2dd78f96
JH
3424 }
3425 else {
e1ec3a88 3426 const char *vile;
3aed30dc
HS
3427 I32 warn_type;
3428
3429 if (gv && io && IoTYPE(io) == IoTYPE_CLOSED) {
3430 vile = "closed";
3431 warn_type = WARN_CLOSED;
3432 }
3433 else {
3434 vile = "unopened";
3435 warn_type = WARN_UNOPENED;
3436 }
3437
3438 if (ckWARN(warn_type)) {
3439 if (name && *name) {
3440 Perl_warner(aTHX_ packWARN(warn_type),
3441 "%s%s on %s %s %s", func, pars, vile, type, name);
3442 if (io && IoDIRP(io) && !(IoFLAGS(io) & IOf_FAKE_DIRP))
3443 Perl_warner(
3444 aTHX_ packWARN(warn_type),
3445 "\t(Are you trying to call %s%s on dirhandle %s?)\n",
3446 func, pars, name
3447 );
3448 }
3449 else {
3450 Perl_warner(aTHX_ packWARN(warn_type),
3451 "%s%s on %s %s", func, pars, vile, type);
3452 if (gv && io && IoDIRP(io) && !(IoFLAGS(io) & IOf_FAKE_DIRP))
3453 Perl_warner(
3454 aTHX_ packWARN(warn_type),
3455 "\t(Are you trying to call %s%s on dirhandle?)\n",
3456 func, pars
3457 );
3458 }
3459 }
bc37a18f 3460 }
69282e91 3461}
a926ef6b
JH
3462
3463#ifdef EBCDIC
cbebf344
JH
3464/* in ASCII order, not that it matters */
3465static const char controllablechars[] = "?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_";
3466
a926ef6b
JH
3467int
3468Perl_ebcdic_control(pTHX_ int ch)
3469{
3aed30dc 3470 if (ch > 'a') {
e1ec3a88 3471 const char *ctlp;
3aed30dc
HS
3472
3473 if (islower(ch))
3474 ch = toupper(ch);
3475
3476 if ((ctlp = strchr(controllablechars, ch)) == 0) {
3477 Perl_die(aTHX_ "unrecognised control character '%c'\n", ch);
a926ef6b 3478 }
3aed30dc
HS
3479
3480 if (ctlp == controllablechars)
3481 return('\177'); /* DEL */
3482 else
3483 return((unsigned char)(ctlp - controllablechars - 1));
3484 } else { /* Want uncontrol */
3485 if (ch == '\177' || ch == -1)
3486 return('?');
3487 else if (ch == '\157')
3488 return('\177');
3489 else if (ch == '\174')
3490 return('\000');
3491 else if (ch == '^') /* '\137' in 1047, '\260' in 819 */
3492 return('\036');
3493 else if (ch == '\155')
3494 return('\037');
3495 else if (0 < ch && ch < (sizeof(controllablechars) - 1))
3496 return(controllablechars[ch+1]);
3497 else
3498 Perl_die(aTHX_ "invalid control request: '\\%03o'\n", ch & 0xFF);
3499 }
a926ef6b
JH
3500}
3501#endif
e72cf795 3502
f6adc668 3503/* To workaround core dumps from the uninitialised tm_zone we get the
e72cf795
JH
3504 * system to give us a reasonable struct to copy. This fix means that
3505 * strftime uses the tm_zone and tm_gmtoff values returned by
3506 * localtime(time()). That should give the desired result most of the
3507 * time. But probably not always!
3508 *
f6adc668
JH
3509 * This does not address tzname aspects of NETaa14816.
3510 *
e72cf795 3511 */
f6adc668 3512
e72cf795
JH
3513#ifdef HAS_GNULIBC
3514# ifndef STRUCT_TM_HASZONE
3515# define STRUCT_TM_HASZONE
3516# endif
3517#endif
3518
f6adc668
JH
3519#ifdef STRUCT_TM_HASZONE /* Backward compat */
3520# ifndef HAS_TM_TM_ZONE
3521# define HAS_TM_TM_ZONE
3522# endif
3523#endif
3524
e72cf795 3525void
f1208910 3526Perl_init_tm(pTHX_ struct tm *ptm) /* see mktime, strftime and asctime */
e72cf795 3527{
f6adc668 3528#ifdef HAS_TM_TM_ZONE
e72cf795 3529 Time_t now;
1b6737cc 3530 const struct tm* my_tm;
e72cf795 3531 (void)time(&now);
82c57498 3532 my_tm = localtime(&now);
ca46b8ee
SP
3533 if (my_tm)
3534 Copy(my_tm, ptm, 1, struct tm);
1b6737cc
AL
3535#else
3536 PERL_UNUSED_ARG(ptm);
e72cf795
JH
3537#endif
3538}
3539
3540/*
3541 * mini_mktime - normalise struct tm values without the localtime()
3542 * semantics (and overhead) of mktime().
3543 */
3544void
f1208910 3545Perl_mini_mktime(pTHX_ struct tm *ptm)
e72cf795
JH
3546{
3547 int yearday;
3548 int secs;
3549 int month, mday, year, jday;
3550 int odd_cent, odd_year;
3551
3552#define DAYS_PER_YEAR 365
3553#define DAYS_PER_QYEAR (4*DAYS_PER_YEAR+1)
3554#define DAYS_PER_CENT (25*DAYS_PER_QYEAR-1)
3555#define DAYS_PER_QCENT (4*DAYS_PER_CENT+1)
3556#define SECS_PER_HOUR (60*60)
3557#define SECS_PER_DAY (24*SECS_PER_HOUR)
3558/* parentheses deliberately absent on these two, otherwise they don't work */
3559#define MONTH_TO_DAYS 153/5
3560#define DAYS_TO_MONTH 5/153
3561/* offset to bias by March (month 4) 1st between month/mday & year finding */
3562#define YEAR_ADJUST (4*MONTH_TO_DAYS+1)
3563/* as used here, the algorithm leaves Sunday as day 1 unless we adjust it */
3564#define WEEKDAY_BIAS 6 /* (1+6)%7 makes Sunday 0 again */
3565
3566/*
3567 * Year/day algorithm notes:
3568 *
3569 * With a suitable offset for numeric value of the month, one can find
3570 * an offset into the year by considering months to have 30.6 (153/5) days,
3571 * using integer arithmetic (i.e., with truncation). To avoid too much
3572 * messing about with leap days, we consider January and February to be
3573 * the 13th and 14th month of the previous year. After that transformation,
3574 * we need the month index we use to be high by 1 from 'normal human' usage,
3575 * so the month index values we use run from 4 through 15.
3576 *
3577 * Given that, and the rules for the Gregorian calendar (leap years are those
3578 * divisible by 4 unless also divisible by 100, when they must be divisible
3579 * by 400 instead), we can simply calculate the number of days since some
3580 * arbitrary 'beginning of time' by futzing with the (adjusted) year number,
3581 * the days we derive from our month index, and adding in the day of the
3582 * month. The value used here is not adjusted for the actual origin which
3583 * it normally would use (1 January A.D. 1), since we're not exposing it.
3584 * We're only building the value so we can turn around and get the
3585 * normalised values for the year, month, day-of-month, and day-of-year.
3586 *
3587 * For going backward, we need to bias the value we're using so that we find
3588 * the right year value. (Basically, we don't want the contribution of
3589 * March 1st to the number to apply while deriving the year). Having done
3590 * that, we 'count up' the contribution to the year number by accounting for
3591 * full quadracenturies (400-year periods) with their extra leap days, plus
3592 * the contribution from full centuries (to avoid counting in the lost leap
3593 * days), plus the contribution from full quad-years (to count in the normal
3594 * leap days), plus the leftover contribution from any non-leap years.
3595 * At this point, if we were working with an actual leap day, we'll have 0
3596 * days left over. This is also true for March 1st, however. So, we have
3597 * to special-case that result, and (earlier) keep track of the 'odd'
3598 * century and year contributions. If we got 4 extra centuries in a qcent,
3599 * or 4 extra years in a qyear, then it's a leap day and we call it 29 Feb.
3600 * Otherwise, we add back in the earlier bias we removed (the 123 from
3601 * figuring in March 1st), find the month index (integer division by 30.6),
3602 * and the remainder is the day-of-month. We then have to convert back to
3603 * 'real' months (including fixing January and February from being 14/15 in
3604 * the previous year to being in the proper year). After that, to get
3605 * tm_yday, we work with the normalised year and get a new yearday value for
3606 * January 1st, which we subtract from the yearday value we had earlier,
3607 * representing the date we've re-built. This is done from January 1
3608 * because tm_yday is 0-origin.
3609 *
3610 * Since POSIX time routines are only guaranteed to work for times since the
3611 * UNIX epoch (00:00:00 1 Jan 1970 UTC), the fact that this algorithm
3612 * applies Gregorian calendar rules even to dates before the 16th century
3613 * doesn't bother me. Besides, you'd need cultural context for a given
3614 * date to know whether it was Julian or Gregorian calendar, and that's
3615 * outside the scope for this routine. Since we convert back based on the
3616 * same rules we used to build the yearday, you'll only get strange results
3617 * for input which needed normalising, or for the 'odd' century years which
3618 * were leap years in the Julian calander but not in the Gregorian one.
3619 * I can live with that.
3620 *
3621