fix File::Spec->abs2rel() to return absolute $path more often for VMS
[p5sagit/p5-mst-13.2.git] / ext / POSIX / POSIX.xs
CommitLineData
6e22d046 1#define PERL_EXT_POSIX
2
2986a63f 3#ifdef NETWARE
4 #define _POSIX_
4efcf9a2 5 /*
6 * Ideally this should be somewhere down in the includes
7 * but putting it in other places is giving compiler errors.
8 * Also here I am unable to check for HAS_UNAME since it wouldn't have
9 * yet come into the file at this stage - sgp 18th Oct 2000
10 */
2986a63f 11 #include <sys/utsname.h>
12#endif /* NETWARE */
13
c5be433b 14#define PERL_NO_GET_CONTEXT
15
463ee0b2 16#include "EXTERN.h"
760ac839 17#define PERLIO_NOT_STDIO 1
463ee0b2 18#include "perl.h"
19#include "XSUB.h"
acfe0abc 20#if defined(PERL_IMPLICIT_SYS)
873ef191 21# undef signal
22# undef open
cd661bb6 23# undef setmode
35ff7856 24# define open PerlLIO_open3
873ef191 25#endif
2304df62 26#include <ctype.h>
a0d0e21e 27#ifdef I_DIRENT /* XXX maybe better to just rely on perl.h? */
2304df62 28#include <dirent.h>
a0d0e21e 29#endif
2304df62 30#include <errno.h>
2304df62 31#ifdef I_FLOAT
32#include <float.h>
33#endif
a0d0e21e 34#ifdef I_LIMITS
2304df62 35#include <limits.h>
a0d0e21e 36#endif
2304df62 37#include <locale.h>
38#include <math.h>
85e6fe83 39#ifdef I_PWD
2304df62 40#include <pwd.h>
85e6fe83 41#endif
2304df62 42#include <setjmp.h>
43#include <signal.h>
2304df62 44#include <stdarg.h>
17c3b450 45
2304df62 46#ifdef I_STDDEF
47#include <stddef.h>
48#endif
6990d991 49
b5846a0b 50#ifdef I_UNISTD
51#include <unistd.h>
52#endif
53
a0d0e21e 54/* XXX This comment is just to make I_TERMIO and I_SGTTY visible to
55 metaconfig for future extension writers. We don't use them in POSIX.
56 (This is really sneaky :-) --AD
57*/
58#if defined(I_TERMIOS)
59#include <termios.h>
60#endif
a0d0e21e 61#ifdef I_STDLIB
2304df62 62#include <stdlib.h>
a0d0e21e 63#endif
5518ecd4 64#ifndef __ultrix__
2304df62 65#include <string.h>
5518ecd4 66#endif
2304df62 67#include <sys/stat.h>
2304df62 68#include <sys/types.h>
2304df62 69#include <time.h>
6dead956 70#ifdef I_UNISTD
1d2dff63 71#include <unistd.h>
6dead956 72#endif
bf4acbe4 73#ifdef MACOS_TRADITIONAL
74#undef fdopen
75#endif
71be2cbc 76#include <fcntl.h>
77
e2465f50 78#ifdef HAS_TZNAME
fb207d52 79# if !defined(WIN32) && !defined(__CYGWIN__) && !defined(NETWARE) && !defined(__UWIN__)
e2465f50 80extern char *tzname[];
81# endif
82#else
fb207d52 83#if !defined(WIN32) && !defined(__UWIN__) || (defined(__MINGW32__) && !defined(tzname))
e2465f50 84char *tzname[] = { "" , "" };
85#endif
cb2479a8 86#endif
87
6c418a22 88#if defined(__VMS) && !defined(__POSIX_SOURCE)
6c418a22 89# include <libdef.h> /* LIB$_INVARG constant */
90# include <lib$routines.h> /* prototype for lib$ediv() */
91# include <starlet.h> /* prototype for sys$gettim() */
774d564b 92# if DECC_VERSION < 50000000
86200d5c 93# define pid_t int /* old versions of DECC miss this in types.h */
774d564b 94# endif
6c418a22 95
6990d991 96# undef mkfifo
6c418a22 97# define mkfifo(a,b) (not_here("mkfifo"),-1)
98# define tzset() not_here("tzset")
99
5f6761f9 100#if ((__VMS_VER >= 70000000) && (__DECC_VER >= 50200000)) || (__CRTL_VER >= 70000000)
101# define HAS_TZNAME /* shows up in VMS 7.0 or Dec C 5.6 */
102# include <utsname.h>
5f6761f9 103# endif /* __VMS_VER >= 70000000 or Dec C 5.6 */
6c418a22 104
105 /* The POSIX notion of ttyname() is better served by getname() under VMS */
106 static char ttnambuf[64];
107# define ttyname(fd) (isatty(fd) > 0 ? getname(fd,ttnambuf,0) : NULL)
108
109 /* The non-POSIX CRTL times() has void return type, so we just get the
110 current time directly */
34f7a5fe 111 clock_t vms_times(struct tms *bufptr) {
d28f7c37 112 dTHX;
6c418a22 113 clock_t retval;
114 /* Get wall time and convert to 10 ms intervals to
115 * produce the return value that the POSIX standard expects */
116# if defined(__DECC) && defined (__ALPHA)
117# include <ints.h>
118 uint64 vmstime;
119 _ckvmssts(sys$gettim(&vmstime));
120 vmstime /= 100000;
121 retval = vmstime & 0x7fffffff;
122# else
123 /* (Older hw or ccs don't have an atomic 64-bit type, so we
124 * juggle 32-bit ints (and a float) to produce a time_t result
125 * with minimal loss of information.) */
126 long int vmstime[2],remainder,divisor = 100000;
127 _ckvmssts(sys$gettim((unsigned long int *)vmstime));
128 vmstime[1] &= 0x7fff; /* prevent overflow in EDIV */
129 _ckvmssts(lib$ediv(&divisor,vmstime,(long int *)&retval,&remainder));
130# endif
131 /* Fill in the struct tms using the CRTL routine . . .*/
34f7a5fe 132 times((tbuffer_t *)bufptr);
6c418a22 133 return (clock_t) retval;
134 }
135# define times(t) vms_times(t)
136#else
d308986b 137#if defined (__CYGWIN__)
f89d6eaa 138# define tzname _tzname
139#endif
2986a63f 140#if defined (WIN32) || defined (NETWARE)
6990d991 141# undef mkfifo
6dead956 142# define mkfifo(a,b) not_here("mkfifo")
873ef191 143# define ttyname(a) (char*)not_here("ttyname")
6dead956 144# define sigset_t long
86200d5c 145# define pid_t long
6dead956 146# ifdef __BORLANDC__
147# define tzname _tzname
148# endif
149# ifdef _MSC_VER
150# define mode_t short
151# endif
62520c91 152# ifdef __MINGW32__
153# define mode_t short
f6c6487a 154# ifndef tzset
155# define tzset() not_here("tzset")
156# endif
157# ifndef _POSIX_OPEN_MAX
158# define _POSIX_OPEN_MAX FOPEN_MAX /* XXX bogus ? */
159# endif
62520c91 160# endif
6dead956 161# define sigaction(a,b,c) not_here("sigaction")
162# define sigpending(a) not_here("sigpending")
163# define sigprocmask(a,b,c) not_here("sigprocmask")
164# define sigsuspend(a) not_here("sigsuspend")
165# define sigemptyset(a) not_here("sigemptyset")
166# define sigaddset(a,b) not_here("sigaddset")
167# define sigdelset(a,b) not_here("sigdelset")
168# define sigfillset(a) not_here("sigfillset")
169# define sigismember(a,b) not_here("sigismember")
2986a63f 170#ifndef NETWARE
6e22d046 171# undef setuid
172# undef setgid
2986a63f 173# define setuid(a) not_here("setuid")
174# define setgid(a) not_here("setgid")
175#endif /* NETWARE */
6dead956 176#else
6990d991 177
178# ifndef HAS_MKFIFO
bf4acbe4 179# if defined(OS2) || defined(MACOS_TRADITIONAL)
d6a255e6 180# define mkfifo(a,b) not_here("mkfifo")
181# else /* !( defined OS2 ) */
182# ifndef mkfifo
183# define mkfifo(path, mode) (mknod((path), (mode) | S_IFIFO, 0))
184# endif
6990d991 185# endif
186# endif /* !HAS_MKFIFO */
187
bf4acbe4 188# ifdef MACOS_TRADITIONAL
bf4acbe4 189# define ttyname(a) (char*)not_here("ttyname")
190# define tzset() not_here("tzset")
191# else
192# include <grp.h>
193# include <sys/times.h>
194# ifdef HAS_UNAME
195# include <sys/utsname.h>
196# endif
197# include <sys/wait.h>
6c418a22 198# endif
6c418a22 199# ifdef I_UTIME
200# include <utime.h>
201# endif
2986a63f 202#endif /* WIN32 || NETWARE */
6dead956 203#endif /* __VMS */
2304df62 204
205typedef int SysRet;
a0d0e21e 206typedef long SysRetLong;
2304df62 207typedef sigset_t* POSIX__SigSet;
208typedef HV* POSIX__SigAction;
a0d0e21e 209#ifdef I_TERMIOS
210typedef struct termios* POSIX__Termios;
211#else /* Define termios types to int, and call not_here for the functions.*/
212#define POSIX__Termios int
213#define speed_t int
214#define tcflag_t int
215#define cc_t int
216#define cfgetispeed(x) not_here("cfgetispeed")
217#define cfgetospeed(x) not_here("cfgetospeed")
218#define tcdrain(x) not_here("tcdrain")
219#define tcflush(x,y) not_here("tcflush")
220#define tcsendbreak(x,y) not_here("tcsendbreak")
221#define cfsetispeed(x,y) not_here("cfsetispeed")
222#define cfsetospeed(x,y) not_here("cfsetospeed")
223#define ctermid(x) (char *) not_here("ctermid")
224#define tcflow(x,y) not_here("tcflow")
225#define tcgetattr(x,y) not_here("tcgetattr")
226#define tcsetattr(x,y,z) not_here("tcsetattr")
227#endif
228
229/* Possibly needed prototypes */
20ce7b12 230char *cuserid (char *);
6e22d046 231#ifndef WIN32
20ce7b12 232double strtod (const char *, char **);
233long strtol (const char *, char **, int);
234unsigned long strtoul (const char *, char **, int);
6e22d046 235#endif
a0d0e21e 236
237#ifndef HAS_CUSERID
238#define cuserid(a) (char *) not_here("cuserid")
239#endif
240#ifndef HAS_DIFFTIME
241#ifndef difftime
242#define difftime(a,b) not_here("difftime")
243#endif
244#endif
245#ifndef HAS_FPATHCONF
246#define fpathconf(f,n) (SysRetLong) not_here("fpathconf")
247#endif
248#ifndef HAS_MKTIME
249#define mktime(a) not_here("mktime")
8990e307 250#endif
251#ifndef HAS_NICE
252#define nice(a) not_here("nice")
253#endif
a0d0e21e 254#ifndef HAS_PATHCONF
255#define pathconf(f,n) (SysRetLong) not_here("pathconf")
256#endif
257#ifndef HAS_SYSCONF
258#define sysconf(n) (SysRetLong) not_here("sysconf")
259#endif
8990e307 260#ifndef HAS_READLINK
261#define readlink(a,b,c) not_here("readlink")
262#endif
263#ifndef HAS_SETPGID
264#define setpgid(a,b) not_here("setpgid")
265#endif
8990e307 266#ifndef HAS_SETSID
267#define setsid() not_here("setsid")
268#endif
a0d0e21e 269#ifndef HAS_STRCOLL
270#define strcoll(s1,s2) not_here("strcoll")
271#endif
a89d8a78 272#ifndef HAS_STRTOD
273#define strtod(s1,s2) not_here("strtod")
274#endif
275#ifndef HAS_STRTOL
276#define strtol(s1,s2,b) not_here("strtol")
277#endif
278#ifndef HAS_STRTOUL
279#define strtoul(s1,s2,b) not_here("strtoul")
280#endif
a0d0e21e 281#ifndef HAS_STRXFRM
282#define strxfrm(s1,s2,n) not_here("strxfrm")
8990e307 283#endif
284#ifndef HAS_TCGETPGRP
285#define tcgetpgrp(a) not_here("tcgetpgrp")
286#endif
287#ifndef HAS_TCSETPGRP
288#define tcsetpgrp(a,b) not_here("tcsetpgrp")
289#endif
290#ifndef HAS_TIMES
2986a63f 291#ifndef NETWARE
8990e307 292#define times(a) not_here("times")
2986a63f 293#endif /* NETWARE */
8990e307 294#endif
295#ifndef HAS_UNAME
296#define uname(a) not_here("uname")
297#endif
298#ifndef HAS_WAITPID
299#define waitpid(a,b,c) not_here("waitpid")
300#endif
301
a0d0e21e 302#ifndef HAS_MBLEN
303#ifndef mblen
304#define mblen(a,b) not_here("mblen")
305#endif
306#endif
307#ifndef HAS_MBSTOWCS
308#define mbstowcs(s, pwcs, n) not_here("mbstowcs")
309#endif
310#ifndef HAS_MBTOWC
311#define mbtowc(pwc, s, n) not_here("mbtowc")
312#endif
313#ifndef HAS_WCSTOMBS
314#define wcstombs(s, pwcs, n) not_here("wcstombs")
315#endif
316#ifndef HAS_WCTOMB
317#define wctomb(s, wchar) not_here("wcstombs")
318#endif
319#if !defined(HAS_MBLEN) && !defined(HAS_MBSTOWCS) && !defined(HAS_MBTOWC) && !defined(HAS_WCSTOMBS) && !defined(HAS_WCTOMB)
320/* If we don't have these functions, then we wouldn't have gotten a typedef
321 for wchar_t, the wide character type. Defining wchar_t allows the
322 functions referencing it to compile. Its actual type is then meaningless,
323 since without the above functions, all sections using it end up calling
324 not_here() and croak. --Kaveh Ghazi (ghazi@noc.rutgers.edu) 9/18/94. */
325#ifndef wchar_t
326#define wchar_t char
327#endif
328#endif
329
330#ifndef HAS_LOCALECONV
331#define localeconv() not_here("localeconv")
332#endif
333
172ea7c8 334#ifdef HAS_LONG_DOUBLE
53796371 335# if LONG_DOUBLESIZE > NVSIZE
172ea7c8 336# undef HAS_LONG_DOUBLE /* XXX until we figure out how to use them */
337# endif
338#endif
339
340#ifndef HAS_LONG_DOUBLE
341#ifdef LDBL_MAX
342#undef LDBL_MAX
343#endif
344#ifdef LDBL_MIN
345#undef LDBL_MIN
346#endif
347#ifdef LDBL_EPSILON
348#undef LDBL_EPSILON
349#endif
350#endif
351
ec193bec 352/* Background: in most systems the low byte of the wait status
353 * is the signal (the lowest 7 bits) and the coredump flag is
354 * the eight bit, and the second lowest byte is the exit status.
355 * BeOS bucks the trend and has the bytes in different order.
356 * See beos/beos.c for how the reality is bent even in BeOS
357 * to follow the traditional. However, to make the POSIX
358 * wait W*() macros to work in BeOS, we need to unbend the
359 * reality back in place. --jhi */
360#ifdef __BEOS__
361# define WMUNGE(x) (((x) & 0xFF00) >> 8 | ((x) & 0x00FF) << 8)
362#else
363# define WMUNGE(x) (x)
364#endif
365
8990e307 366static int
f0f333f4 367not_here(char *s)
8990e307 368{
369 croak("POSIX::%s not implemented on this architecture", s);
370 return -1;
371}
463ee0b2 372
1cb0fb50 373#include "const-c.inc"
a290f238 374
375/* These were implemented in the old "constant" subroutine. They are actually
376 macros that take an integer argument and return an integer result. */
377static int
378int_macro_int (const char *name, STRLEN len, IV *arg_result) {
379 /* Initially switch on the length of the name. */
380 /* This code has been edited from a "constant" function generated by:
381
382use ExtUtils::Constant qw (constant_types C_constant XS_constant);
383
384my $types = {map {($_, 1)} qw(IV)};
385my @names = (qw(S_ISBLK S_ISCHR S_ISDIR S_ISFIFO S_ISREG WEXITSTATUS WIFEXITED
386 WIFSIGNALED WIFSTOPPED WSTOPSIG WTERMSIG));
387
388print constant_types(); # macro defs
389foreach (C_constant ("POSIX", 'int_macro_int', 'IV', $types, undef, 5, @names) ) {
390 print $_, "\n"; # C constant subs
391}
392print "#### XS Section:\n";
393print XS_constant ("POSIX", $types);
394__END__
395 */
396
397 switch (len) {
398 case 7:
399 /* Names all of length 7. */
400 /* S_ISBLK S_ISCHR S_ISDIR S_ISREG */
401 /* Offset 5 gives the best switch position. */
402 switch (name[5]) {
403 case 'E':
404 if (memEQ(name, "S_ISREG", 7)) {
405 /* ^ */
406#ifdef S_ISREG
407 *arg_result = S_ISREG(*arg_result);
408 return PERL_constant_ISIV;
2304df62 409#else
a290f238 410 return PERL_constant_NOTDEF;
2304df62 411#endif
a290f238 412 }
413 break;
414 case 'H':
415 if (memEQ(name, "S_ISCHR", 7)) {
416 /* ^ */
417#ifdef S_ISCHR
418 *arg_result = S_ISCHR(*arg_result);
419 return PERL_constant_ISIV;
2304df62 420#else
a290f238 421 return PERL_constant_NOTDEF;
2304df62 422#endif
a290f238 423 }
424 break;
425 case 'I':
426 if (memEQ(name, "S_ISDIR", 7)) {
427 /* ^ */
428#ifdef S_ISDIR
429 *arg_result = S_ISDIR(*arg_result);
430 return PERL_constant_ISIV;
2304df62 431#else
a290f238 432 return PERL_constant_NOTDEF;
2304df62 433#endif
a290f238 434 }
435 break;
436 case 'L':
437 if (memEQ(name, "S_ISBLK", 7)) {
438 /* ^ */
439#ifdef S_ISBLK
440 *arg_result = S_ISBLK(*arg_result);
441 return PERL_constant_ISIV;
2304df62 442#else
a290f238 443 return PERL_constant_NOTDEF;
2304df62 444#endif
a290f238 445 }
446 break;
447 }
448 break;
449 case 8:
450 /* Names all of length 8. */
451 /* S_ISFIFO WSTOPSIG WTERMSIG */
452 /* Offset 3 gives the best switch position. */
453 switch (name[3]) {
454 case 'O':
455 if (memEQ(name, "WSTOPSIG", 8)) {
456 /* ^ */
457#ifdef WSTOPSIG
bfbc3223 458 int i = *arg_result;
459 *arg_result = WSTOPSIG(WMUNGE(i));
a290f238 460 return PERL_constant_ISIV;
2304df62 461#else
a290f238 462 return PERL_constant_NOTDEF;
2304df62 463#endif
a290f238 464 }
465 break;
466 case 'R':
467 if (memEQ(name, "WTERMSIG", 8)) {
468 /* ^ */
469#ifdef WTERMSIG
bfbc3223 470 int i = *arg_result;
471 *arg_result = WTERMSIG(WMUNGE(i));
a290f238 472 return PERL_constant_ISIV;
2304df62 473#else
a290f238 474 return PERL_constant_NOTDEF;
2304df62 475#endif
a290f238 476 }
477 break;
478 case 'S':
479 if (memEQ(name, "S_ISFIFO", 8)) {
480 /* ^ */
481#ifdef S_ISFIFO
482 *arg_result = S_ISFIFO(*arg_result);
483 return PERL_constant_ISIV;
2304df62 484#else
a290f238 485 return PERL_constant_NOTDEF;
2304df62 486#endif
a290f238 487 }
488 break;
489 }
490 break;
491 case 9:
492 if (memEQ(name, "WIFEXITED", 9)) {
493#ifdef WIFEXITED
bfbc3223 494 int i = *arg_result;
495 *arg_result = WIFEXITED(WMUNGE(i));
a290f238 496 return PERL_constant_ISIV;
2304df62 497#else
a290f238 498 return PERL_constant_NOTDEF;
2304df62 499#endif
a290f238 500 }
501 break;
502 case 10:
503 if (memEQ(name, "WIFSTOPPED", 10)) {
504#ifdef WIFSTOPPED
bfbc3223 505 int i = *arg_result;
506 *arg_result = WIFSTOPPED(WMUNGE(i));
a290f238 507 return PERL_constant_ISIV;
2304df62 508#else
a290f238 509 return PERL_constant_NOTDEF;
2304df62 510#endif
a290f238 511 }
512 break;
513 case 11:
514 /* Names all of length 11. */
515 /* WEXITSTATUS WIFSIGNALED */
516 /* Offset 1 gives the best switch position. */
517 switch (name[1]) {
518 case 'E':
519 if (memEQ(name, "WEXITSTATUS", 11)) {
520 /* ^ */
521#ifdef WEXITSTATUS
bfbc3223 522 int i = *arg_result;
523 *arg_result = WEXITSTATUS(WMUNGE(i));
a290f238 524 return PERL_constant_ISIV;
2304df62 525#else
a290f238 526 return PERL_constant_NOTDEF;
2304df62 527#endif
a290f238 528 }
529 break;
530 case 'I':
531 if (memEQ(name, "WIFSIGNALED", 11)) {
532 /* ^ */
533#ifdef WIFSIGNALED
bfbc3223 534 int i = *arg_result;
535 *arg_result = WIFSIGNALED(WMUNGE(i));
a290f238 536 return PERL_constant_ISIV;
2304df62 537#else
a290f238 538 return PERL_constant_NOTDEF;
2304df62 539#endif
a290f238 540 }
541 break;
542 }
543 break;
544 }
545 return PERL_constant_NOTFOUND;
546}
547
1dfe7606 548static void
40b7a5f5 549restore_sigmask(pTHX_ SV *osset_sv)
1dfe7606 550{
7feb700b 551 /* Fortunately, restoring the signal mask can't fail, because
552 * there's nothing we can do about it if it does -- we're not
553 * supposed to return -1 from sigaction unless the disposition
554 * was unaffected.
555 */
7feb700b 556 sigset_t *ossetp = (sigset_t *) SvPV_nolen( osset_sv );
557 (void)sigprocmask(SIG_SETMASK, ossetp, (sigset_t *)0);
1dfe7606 558}
559
2304df62 560MODULE = SigSet PACKAGE = POSIX::SigSet PREFIX = sig
561
562POSIX::SigSet
563new(packname = "POSIX::SigSet", ...)
564 char * packname
565 CODE:
566 {
567 int i;
01667c76 568 New(0, RETVAL, 1, sigset_t);
2304df62 569 sigemptyset(RETVAL);
a0d0e21e 570 for (i = 1; i < items; i++)
2304df62 571 sigaddset(RETVAL, SvIV(ST(i)));
572 }
573 OUTPUT:
574 RETVAL
463ee0b2 575
8990e307 576void
2304df62 577DESTROY(sigset)
578 POSIX::SigSet sigset
579 CODE:
01667c76 580 Safefree(sigset);
2304df62 581
582SysRet
583sigaddset(sigset, sig)
584 POSIX::SigSet sigset
585 int sig
586
587SysRet
588sigdelset(sigset, sig)
589 POSIX::SigSet sigset
590 int sig
591
592SysRet
593sigemptyset(sigset)
594 POSIX::SigSet sigset
595
596SysRet
597sigfillset(sigset)
598 POSIX::SigSet sigset
599
600int
601sigismember(sigset, sig)
602 POSIX::SigSet sigset
603 int sig
604
605
a0d0e21e 606MODULE = Termios PACKAGE = POSIX::Termios PREFIX = cf
607
608POSIX::Termios
609new(packname = "POSIX::Termios", ...)
610 char * packname
611 CODE:
612 {
613#ifdef I_TERMIOS
01667c76 614 New(0, RETVAL, 1, struct termios);
a0d0e21e 615#else
616 not_here("termios");
640cc986 617 RETVAL = 0;
a0d0e21e 618#endif
619 }
620 OUTPUT:
621 RETVAL
622
623void
624DESTROY(termios_ref)
625 POSIX::Termios termios_ref
626 CODE:
627#ifdef I_TERMIOS
01667c76 628 Safefree(termios_ref);
a0d0e21e 629#else
630 not_here("termios");
631#endif
632
633SysRet
634getattr(termios_ref, fd = 0)
635 POSIX::Termios termios_ref
636 int fd
637 CODE:
638 RETVAL = tcgetattr(fd, termios_ref);
639 OUTPUT:
640 RETVAL
641
642SysRet
643setattr(termios_ref, fd = 0, optional_actions = 0)
644 POSIX::Termios termios_ref
645 int fd
646 int optional_actions
647 CODE:
648 RETVAL = tcsetattr(fd, optional_actions, termios_ref);
649 OUTPUT:
650 RETVAL
651
652speed_t
653cfgetispeed(termios_ref)
654 POSIX::Termios termios_ref
655
656speed_t
657cfgetospeed(termios_ref)
658 POSIX::Termios termios_ref
659
660tcflag_t
661getiflag(termios_ref)
662 POSIX::Termios termios_ref
663 CODE:
664#ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
665 RETVAL = termios_ref->c_iflag;
666#else
640cc986 667 not_here("getiflag");
668 RETVAL = 0;
a0d0e21e 669#endif
670 OUTPUT:
671 RETVAL
672
673tcflag_t
674getoflag(termios_ref)
675 POSIX::Termios termios_ref
676 CODE:
677#ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
678 RETVAL = termios_ref->c_oflag;
679#else
640cc986 680 not_here("getoflag");
681 RETVAL = 0;
a0d0e21e 682#endif
683 OUTPUT:
684 RETVAL
685
686tcflag_t
687getcflag(termios_ref)
688 POSIX::Termios termios_ref
689 CODE:
690#ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
691 RETVAL = termios_ref->c_cflag;
692#else
640cc986 693 not_here("getcflag");
694 RETVAL = 0;
a0d0e21e 695#endif
696 OUTPUT:
697 RETVAL
698
699tcflag_t
700getlflag(termios_ref)
701 POSIX::Termios termios_ref
702 CODE:
703#ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
704 RETVAL = termios_ref->c_lflag;
705#else
640cc986 706 not_here("getlflag");
707 RETVAL = 0;
a0d0e21e 708#endif
709 OUTPUT:
710 RETVAL
711
712cc_t
713getcc(termios_ref, ccix)
714 POSIX::Termios termios_ref
715 int ccix
716 CODE:
717#ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
718 if (ccix >= NCCS)
719 croak("Bad getcc subscript");
720 RETVAL = termios_ref->c_cc[ccix];
721#else
640cc986 722 not_here("getcc");
723 RETVAL = 0;
a0d0e21e 724#endif
725 OUTPUT:
726 RETVAL
727
728SysRet
729cfsetispeed(termios_ref, speed)
730 POSIX::Termios termios_ref
731 speed_t speed
732
733SysRet
734cfsetospeed(termios_ref, speed)
735 POSIX::Termios termios_ref
736 speed_t speed
737
738void
739setiflag(termios_ref, iflag)
740 POSIX::Termios termios_ref
741 tcflag_t iflag
742 CODE:
743#ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
744 termios_ref->c_iflag = iflag;
745#else
746 not_here("setiflag");
747#endif
748
749void
750setoflag(termios_ref, oflag)
751 POSIX::Termios termios_ref
752 tcflag_t oflag
753 CODE:
754#ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
755 termios_ref->c_oflag = oflag;
756#else
757 not_here("setoflag");
758#endif
759
760void
761setcflag(termios_ref, cflag)
762 POSIX::Termios termios_ref
763 tcflag_t cflag
764 CODE:
765#ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
766 termios_ref->c_cflag = cflag;
767#else
768 not_here("setcflag");
769#endif
770
771void
772setlflag(termios_ref, lflag)
773 POSIX::Termios termios_ref
774 tcflag_t lflag
775 CODE:
776#ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
777 termios_ref->c_lflag = lflag;
778#else
779 not_here("setlflag");
780#endif
781
782void
783setcc(termios_ref, ccix, cc)
784 POSIX::Termios termios_ref
785 int ccix
786 cc_t cc
787 CODE:
788#ifdef I_TERMIOS /* References a termios structure member so ifdef it out. */
789 if (ccix >= NCCS)
790 croak("Bad setcc subscript");
791 termios_ref->c_cc[ccix] = cc;
792#else
793 not_here("setcc");
794#endif
795
796
a0d0e21e 797MODULE = POSIX PACKAGE = POSIX
798
1cb0fb50 799INCLUDE: const-xs.inc
a290f238 800
801void
802int_macro_int(sv, iv)
803 PREINIT:
804 dXSTARG;
805 STRLEN len;
806 int type;
807 INPUT:
808 SV * sv;
809 const char * s = SvPV(sv, len);
810 IV iv;
811 PPCODE:
812 /* Change this to int_macro_int(s, len, &iv, &nv);
813 if you need to return both NVs and IVs */
814 type = int_macro_int(s, len, &iv);
815 /* Return 1 or 2 items. First is error message, or undef if no error.
816 Second, if present, is found value */
817 switch (type) {
818 case PERL_constant_NOTFOUND:
819 sv = sv_2mortal(newSVpvf("%s is not a valid POSIX macro", s));
820 EXTEND(SP, 1);
821 PUSHs(&PL_sv_undef);
822 PUSHs(sv);
823 break;
824 case PERL_constant_NOTDEF:
825 sv = sv_2mortal(newSVpvf(
826 "Your vendor has not defined POSIX macro %s, used", s));
827 EXTEND(SP, 1);
828 PUSHs(&PL_sv_undef);
829 PUSHs(sv);
830 break;
831 case PERL_constant_ISIV:
832 PUSHi(iv);
833 break;
834 default:
835 sv = sv_2mortal(newSVpvf(
836 "Unexpected return type %d while processing POSIX macro %s, used",
837 type, s));
838 EXTEND(SP, 1);
839 PUSHs(&PL_sv_undef);
840 PUSHs(sv);
841 }
2304df62 842
843int
844isalnum(charstring)
5344da4e 845 unsigned char * charstring
2304df62 846 CODE:
5344da4e 847 unsigned char *s = charstring;
d4e900e0 848 unsigned char *e = s + SvCUR(ST(0));
5344da4e 849 for (RETVAL = 1; RETVAL && s < e; s++)
2304df62 850 if (!isalnum(*s))
851 RETVAL = 0;
852 OUTPUT:
853 RETVAL
854
855int
856isalpha(charstring)
5344da4e 857 unsigned char * charstring
2304df62 858 CODE:
5344da4e 859 unsigned char *s = charstring;
d4e900e0 860 unsigned char *e = s + SvCUR(ST(0));
5344da4e 861 for (RETVAL = 1; RETVAL && s < e; s++)
2304df62 862 if (!isalpha(*s))
863 RETVAL = 0;
864 OUTPUT:
865 RETVAL
866
867int
868iscntrl(charstring)
5344da4e 869 unsigned char * charstring
2304df62 870 CODE:
5344da4e 871 unsigned char *s = charstring;
d4e900e0 872 unsigned char *e = s + SvCUR(ST(0));
5344da4e 873 for (RETVAL = 1; RETVAL && s < e; s++)
2304df62 874 if (!iscntrl(*s))
875 RETVAL = 0;
876 OUTPUT:
877 RETVAL
878
879int
880isdigit(charstring)
5344da4e 881 unsigned char * charstring
2304df62 882 CODE:
5344da4e 883 unsigned char *s = charstring;
d4e900e0 884 unsigned char *e = s + SvCUR(ST(0));
5344da4e 885 for (RETVAL = 1; RETVAL && s < e; s++)
2304df62 886 if (!isdigit(*s))
887 RETVAL = 0;
888 OUTPUT:
889 RETVAL
890
891int
892isgraph(charstring)
5344da4e 893 unsigned char * charstring
2304df62 894 CODE:
5344da4e 895 unsigned char *s = charstring;
d4e900e0 896 unsigned char *e = s + SvCUR(ST(0));
5344da4e 897 for (RETVAL = 1; RETVAL && s < e; s++)
2304df62 898 if (!isgraph(*s))
899 RETVAL = 0;
900 OUTPUT:
901 RETVAL
902
903int
904islower(charstring)
5344da4e 905 unsigned char * charstring
2304df62 906 CODE:
5344da4e 907 unsigned char *s = charstring;
d4e900e0 908 unsigned char *e = s + SvCUR(ST(0));
5344da4e 909 for (RETVAL = 1; RETVAL && s < e; s++)
2304df62 910 if (!islower(*s))
911 RETVAL = 0;
912 OUTPUT:
913 RETVAL
914
915int
916isprint(charstring)
5344da4e 917 unsigned char * charstring
2304df62 918 CODE:
5344da4e 919 unsigned char *s = charstring;
d4e900e0 920 unsigned char *e = s + SvCUR(ST(0));
5344da4e 921 for (RETVAL = 1; RETVAL && s < e; s++)
2304df62 922 if (!isprint(*s))
923 RETVAL = 0;
924 OUTPUT:
925 RETVAL
926
927int
928ispunct(charstring)
5344da4e 929 unsigned char * charstring
2304df62 930 CODE:
5344da4e 931 unsigned char *s = charstring;
d4e900e0 932 unsigned char *e = s + SvCUR(ST(0));
5344da4e 933 for (RETVAL = 1; RETVAL && s < e; s++)
2304df62 934 if (!ispunct(*s))
935 RETVAL = 0;
936 OUTPUT:
937 RETVAL
938
939int
940isspace(charstring)
5344da4e 941 unsigned char * charstring
2304df62 942 CODE:
5344da4e 943 unsigned char *s = charstring;
d4e900e0 944 unsigned char *e = s + SvCUR(ST(0));
5344da4e 945 for (RETVAL = 1; RETVAL && s < e; s++)
2304df62 946 if (!isspace(*s))
947 RETVAL = 0;
948 OUTPUT:
949 RETVAL
8990e307 950
951int
2304df62 952isupper(charstring)
5344da4e 953 unsigned char * charstring
2304df62 954 CODE:
5344da4e 955 unsigned char *s = charstring;
d4e900e0 956 unsigned char *e = s + SvCUR(ST(0));
5344da4e 957 for (RETVAL = 1; RETVAL && s < e; s++)
2304df62 958 if (!isupper(*s))
959 RETVAL = 0;
960 OUTPUT:
961 RETVAL
8990e307 962
963int
2304df62 964isxdigit(charstring)
5344da4e 965 unsigned char * charstring
2304df62 966 CODE:
5344da4e 967 unsigned char *s = charstring;
d4e900e0 968 unsigned char *e = s + SvCUR(ST(0));
5344da4e 969 for (RETVAL = 1; RETVAL && s < e; s++)
2304df62 970 if (!isxdigit(*s))
971 RETVAL = 0;
972 OUTPUT:
973 RETVAL
974
975SysRet
976open(filename, flags = O_RDONLY, mode = 0666)
977 char * filename
978 int flags
a0d0e21e 979 Mode_t mode
748a9306 980 CODE:
981 if (flags & (O_APPEND|O_CREAT|O_TRUNC|O_RDWR|O_WRONLY|O_EXCL))
982 TAINT_PROPER("open");
983 RETVAL = open(filename, flags, mode);
984 OUTPUT:
985 RETVAL
986
2304df62 987
988HV *
989localeconv()
990 CODE:
a0d0e21e 991#ifdef HAS_LOCALECONV
2304df62 992 struct lconv *lcbuf;
993 RETVAL = newHV();
8063af02 994 if ((lcbuf = localeconv())) {
2304df62 995 /* the strings */
996 if (lcbuf->decimal_point && *lcbuf->decimal_point)
997 hv_store(RETVAL, "decimal_point", 13,
998 newSVpv(lcbuf->decimal_point, 0), 0);
999 if (lcbuf->thousands_sep && *lcbuf->thousands_sep)
1000 hv_store(RETVAL, "thousands_sep", 13,
1001 newSVpv(lcbuf->thousands_sep, 0), 0);
28e8609d 1002#ifndef NO_LOCALECONV_GROUPING
2304df62 1003 if (lcbuf->grouping && *lcbuf->grouping)
1004 hv_store(RETVAL, "grouping", 8,
1005 newSVpv(lcbuf->grouping, 0), 0);
28e8609d 1006#endif
2304df62 1007 if (lcbuf->int_curr_symbol && *lcbuf->int_curr_symbol)
1008 hv_store(RETVAL, "int_curr_symbol", 15,
1009 newSVpv(lcbuf->int_curr_symbol, 0), 0);
1010 if (lcbuf->currency_symbol && *lcbuf->currency_symbol)
1011 hv_store(RETVAL, "currency_symbol", 15,
1012 newSVpv(lcbuf->currency_symbol, 0), 0);
1013 if (lcbuf->mon_decimal_point && *lcbuf->mon_decimal_point)
1014 hv_store(RETVAL, "mon_decimal_point", 17,
1015 newSVpv(lcbuf->mon_decimal_point, 0), 0);
39e571d4 1016#ifndef NO_LOCALECONV_MON_THOUSANDS_SEP
2304df62 1017 if (lcbuf->mon_thousands_sep && *lcbuf->mon_thousands_sep)
1018 hv_store(RETVAL, "mon_thousands_sep", 17,
1019 newSVpv(lcbuf->mon_thousands_sep, 0), 0);
39e571d4 1020#endif
28e8609d 1021#ifndef NO_LOCALECONV_MON_GROUPING
2304df62 1022 if (lcbuf->mon_grouping && *lcbuf->mon_grouping)
1023 hv_store(RETVAL, "mon_grouping", 12,
1024 newSVpv(lcbuf->mon_grouping, 0), 0);
28e8609d 1025#endif
2304df62 1026 if (lcbuf->positive_sign && *lcbuf->positive_sign)
1027 hv_store(RETVAL, "positive_sign", 13,
1028 newSVpv(lcbuf->positive_sign, 0), 0);
1029 if (lcbuf->negative_sign && *lcbuf->negative_sign)
1030 hv_store(RETVAL, "negative_sign", 13,
1031 newSVpv(lcbuf->negative_sign, 0), 0);
1032 /* the integers */
1033 if (lcbuf->int_frac_digits != CHAR_MAX)
1034 hv_store(RETVAL, "int_frac_digits", 15,
1035 newSViv(lcbuf->int_frac_digits), 0);
1036 if (lcbuf->frac_digits != CHAR_MAX)
1037 hv_store(RETVAL, "frac_digits", 11,
1038 newSViv(lcbuf->frac_digits), 0);
1039 if (lcbuf->p_cs_precedes != CHAR_MAX)
1040 hv_store(RETVAL, "p_cs_precedes", 13,
1041 newSViv(lcbuf->p_cs_precedes), 0);
1042 if (lcbuf->p_sep_by_space != CHAR_MAX)
1043 hv_store(RETVAL, "p_sep_by_space", 14,
1044 newSViv(lcbuf->p_sep_by_space), 0);
1045 if (lcbuf->n_cs_precedes != CHAR_MAX)
1046 hv_store(RETVAL, "n_cs_precedes", 13,
1047 newSViv(lcbuf->n_cs_precedes), 0);
1048 if (lcbuf->n_sep_by_space != CHAR_MAX)
1049 hv_store(RETVAL, "n_sep_by_space", 14,
1050 newSViv(lcbuf->n_sep_by_space), 0);
1051 if (lcbuf->p_sign_posn != CHAR_MAX)
1052 hv_store(RETVAL, "p_sign_posn", 11,
1053 newSViv(lcbuf->p_sign_posn), 0);
1054 if (lcbuf->n_sign_posn != CHAR_MAX)
1055 hv_store(RETVAL, "n_sign_posn", 11,
1056 newSViv(lcbuf->n_sign_posn), 0);
1057 }
a0d0e21e 1058#else
1059 localeconv(); /* A stub to call not_here(). */
1060#endif
2304df62 1061 OUTPUT:
1062 RETVAL
1063
1064char *
c28ee57b 1065setlocale(category, locale = 0)
2304df62 1066 int category
1067 char * locale
c28ee57b 1068 CODE:
1069 RETVAL = setlocale(category, locale);
bbce6d69 1070 if (RETVAL) {
36477c24 1071#ifdef USE_LOCALE_CTYPE
bbce6d69 1072 if (category == LC_CTYPE
1073#ifdef LC_ALL
1074 || category == LC_ALL
1075#endif
1076 )
1077 {
1078 char *newctype;
1079#ifdef LC_ALL
1080 if (category == LC_ALL)
1081 newctype = setlocale(LC_CTYPE, NULL);
1082 else
1083#endif
1084 newctype = RETVAL;
864dbfa3 1085 new_ctype(newctype);
bbce6d69 1086 }
36477c24 1087#endif /* USE_LOCALE_CTYPE */
1088#ifdef USE_LOCALE_COLLATE
bbce6d69 1089 if (category == LC_COLLATE
1090#ifdef LC_ALL
1091 || category == LC_ALL
1092#endif
1093 )
1094 {
1095 char *newcoll;
1096#ifdef LC_ALL
1097 if (category == LC_ALL)
1098 newcoll = setlocale(LC_COLLATE, NULL);
1099 else
1100#endif
1101 newcoll = RETVAL;
864dbfa3 1102 new_collate(newcoll);
bbce6d69 1103 }
36477c24 1104#endif /* USE_LOCALE_COLLATE */
1105#ifdef USE_LOCALE_NUMERIC
bbce6d69 1106 if (category == LC_NUMERIC
1107#ifdef LC_ALL
1108 || category == LC_ALL
1109#endif
1110 )
1111 {
1112 char *newnum;
1113#ifdef LC_ALL
1114 if (category == LC_ALL)
1115 newnum = setlocale(LC_NUMERIC, NULL);
1116 else
1117#endif
1118 newnum = RETVAL;
864dbfa3 1119 new_numeric(newnum);
bbce6d69 1120 }
36477c24 1121#endif /* USE_LOCALE_NUMERIC */
bbce6d69 1122 }
c28ee57b 1123 OUTPUT:
1124 RETVAL
1125
2304df62 1126
e1ca407b 1127NV
2304df62 1128acos(x)
e1ca407b 1129 NV x
2304df62 1130
e1ca407b 1131NV
2304df62 1132asin(x)
e1ca407b 1133 NV x
2304df62 1134
e1ca407b 1135NV
2304df62 1136atan(x)
e1ca407b 1137 NV x
2304df62 1138
e1ca407b 1139NV
2304df62 1140ceil(x)
e1ca407b 1141 NV x
2304df62 1142
e1ca407b 1143NV
2304df62 1144cosh(x)
e1ca407b 1145 NV x
2304df62 1146
e1ca407b 1147NV
2304df62 1148floor(x)
e1ca407b 1149 NV x
2304df62 1150
e1ca407b 1151NV
2304df62 1152fmod(x,y)
e1ca407b 1153 NV x
1154 NV y
2304df62 1155
1156void
1157frexp(x)
e1ca407b 1158 NV x
2304df62 1159 PPCODE:
1160 int expvar;
2304df62 1161 /* (We already know stack is long enough.) */
1162 PUSHs(sv_2mortal(newSVnv(frexp(x,&expvar))));
1163 PUSHs(sv_2mortal(newSViv(expvar)));
1164
e1ca407b 1165NV
2304df62 1166ldexp(x,exp)
e1ca407b 1167 NV x
2304df62 1168 int exp
1169
e1ca407b 1170NV
2304df62 1171log10(x)
e1ca407b 1172 NV x
2304df62 1173
1174void
1175modf(x)
e1ca407b 1176 NV x
2304df62 1177 PPCODE:
e1ca407b 1178 NV intvar;
2304df62 1179 /* (We already know stack is long enough.) */
bf4acbe4 1180 PUSHs(sv_2mortal(newSVnv(Perl_modf(x,&intvar))));
2304df62 1181 PUSHs(sv_2mortal(newSVnv(intvar)));
1182
e1ca407b 1183NV
2304df62 1184sinh(x)
e1ca407b 1185 NV x
2304df62 1186
e1ca407b 1187NV
3b35bae3 1188tan(x)
e1ca407b 1189 NV x
3b35bae3 1190
e1ca407b 1191NV
2304df62 1192tanh(x)
e1ca407b 1193 NV x
2304df62 1194
1195SysRet
1dfe7606 1196sigaction(sig, optaction, oldaction = 0)
2304df62 1197 int sig
1dfe7606 1198 SV * optaction
2304df62 1199 POSIX::SigAction oldaction
1200 CODE:
2986a63f 1201#if defined(WIN32) || defined(NETWARE)
6dead956 1202 RETVAL = not_here("sigaction");
1203#else
2304df62 1204# This code is really grody because we're trying to make the signal
1205# interface look beautiful, which is hard.
1206
2304df62 1207 {
1dfe7606 1208 POSIX__SigAction action;
f4c556ac 1209 GV *siggv = gv_fetchpv("SIG", TRUE, SVt_PVHV);
2304df62 1210 struct sigaction act;
1211 struct sigaction oact;
1dfe7606 1212 sigset_t sset;
183bde56 1213 SV *osset_sv;
27c1a449 1214 sigset_t osset;
2304df62 1215 POSIX__SigSet sigset;
1216 SV** svp;
1d81eac9 1217 SV** sigsvp;
1218 if (sig == 0 && SvPOK(ST(0))) {
1219 char *s = SvPVX(ST(0));
1220 int i = whichsig(s);
1221
1222 if (i < 0 && memEQ(s, "SIG", 3))
1223 i = whichsig(s + 3);
1224 if (i < 0) {
1225 if (ckWARN(WARN_SIGNAL))
1226 Perl_warner(aTHX_ packWARN(WARN_SIGNAL),
1227 "No such signal: SIG%s", s);
1228 XSRETURN_UNDEF;
1229 }
1230 else
1231 sig = i;
1232 }
1233 sigsvp = hv_fetch(GvHVn(siggv),
1234 PL_sig_name[sig],
1235 strlen(PL_sig_name[sig]),
1236 TRUE);
2304df62 1237
1dfe7606 1238 /* Check optaction and set action */
1239 if(SvTRUE(optaction)) {
1240 if(sv_isa(optaction, "POSIX::SigAction"))
1241 action = (HV*)SvRV(optaction);
1242 else
1243 croak("action is not of type POSIX::SigAction");
1244 }
1245 else {
1246 action=0;
1247 }
1248
1249 /* sigaction() is supposed to look atomic. In particular, any
1250 * signal handler invoked during a sigaction() call should
1251 * see either the old or the new disposition, and not something
1252 * in between. We use sigprocmask() to make it so.
1253 */
1254 sigfillset(&sset);
1255 RETVAL=sigprocmask(SIG_BLOCK, &sset, &osset);
1256 if(RETVAL == -1)
15c0d34a 1257 XSRETURN_UNDEF;
1dfe7606 1258 ENTER;
1259 /* Restore signal mask no matter how we exit this block. */
183bde56 1260 osset_sv = newSVpv((char *)(&osset), sizeof(sigset_t));
1261 SAVEFREESV( osset_sv );
40b7a5f5 1262 SAVEDESTRUCTOR_X(restore_sigmask, osset_sv);
1dfe7606 1263
1264 RETVAL=-1; /* In case both oldaction and action are 0. */
1265
1266 /* Remember old disposition if desired. */
2304df62 1267 if (oldaction) {
2304df62 1268 svp = hv_fetch(oldaction, "HANDLER", 7, TRUE);
1dfe7606 1269 if(!svp)
1270 croak("Can't supply an oldaction without a HANDLER");
1271 if(SvTRUE(*sigsvp)) { /* TBD: what if "0"? */
1272 sv_setsv(*svp, *sigsvp);
1273 }
1274 else {
1275 sv_setpv(*svp, "DEFAULT");
1276 }
1277 RETVAL = sigaction(sig, (struct sigaction *)0, & oact);
1278 if(RETVAL == -1)
15c0d34a 1279 XSRETURN_UNDEF;
1dfe7606 1280 /* Get back the mask. */
1281 svp = hv_fetch(oldaction, "MASK", 4, TRUE);
1282 if (sv_isa(*svp, "POSIX::SigSet")) {
1283 IV tmp = SvIV((SV*)SvRV(*svp));
1284 sigset = INT2PTR(sigset_t*, tmp);
1285 }
1286 else {
1287 New(0, sigset, 1, sigset_t);
1288 sv_setptrobj(*svp, sigset, "POSIX::SigSet");
1289 }
1290 *sigset = oact.sa_mask;
1291
1292 /* Get back the flags. */
1293 svp = hv_fetch(oldaction, "FLAGS", 5, TRUE);
1294 sv_setiv(*svp, oact.sa_flags);
d36b6582 1295
1296 /* Get back whether the old handler used safe signals. */
1297 svp = hv_fetch(oldaction, "SAFE", 4, TRUE);
5c1546dc 1298 sv_setiv(*svp, oact.sa_handler == PL_csighandlerp);
2304df62 1299 }
1300
1301 if (action) {
d36b6582 1302 /* Safe signals use "csighandler", which vectors through the
1303 PL_sighandlerp pointer when it's safe to do so.
1304 (BTW, "csighandler" is very different from "sighandler".) */
1305 svp = hv_fetch(action, "SAFE", 4, FALSE);
1306 act.sa_handler = (*svp && SvTRUE(*svp))
b4ed63f0 1307 ? PL_csighandlerp : PL_sighandlerp;
d36b6582 1308
1309 /* Vector new Perl handler through %SIG.
1310 (The core signal handlers read %SIG to dispatch.) */
2304df62 1311 svp = hv_fetch(action, "HANDLER", 7, FALSE);
1312 if (!svp)
1313 croak("Can't supply an action without a HANDLER");
1dfe7606 1314 sv_setsv(*sigsvp, *svp);
d36b6582 1315
1316 /* This call actually calls sigaction() with almost the
1317 right settings, including appropriate interpretation
1318 of DEFAULT and IGNORE. However, why are we doing
1319 this when we're about to do it again just below? XXX */
1320 mg_set(*sigsvp);
1321
1322 /* And here again we duplicate -- DEFAULT/IGNORE checking. */
1dfe7606 1323 if(SvPOK(*svp)) {
1324 char *s=SvPVX(*svp);
1325 if(strEQ(s,"IGNORE")) {
1326 act.sa_handler = SIG_IGN;
1327 }
1328 else if(strEQ(s,"DEFAULT")) {
1329 act.sa_handler = SIG_DFL;
1330 }
1dfe7606 1331 }
2304df62 1332
1333 /* Set up any desired mask. */
1334 svp = hv_fetch(action, "MASK", 4, FALSE);
1335 if (svp && sv_isa(*svp, "POSIX::SigSet")) {
ac634a9a 1336 IV tmp = SvIV((SV*)SvRV(*svp));
1dfe7606 1337 sigset = INT2PTR(sigset_t*, tmp);
2304df62 1338 act.sa_mask = *sigset;
1339 }
1340 else
85e6fe83 1341 sigemptyset(& act.sa_mask);
2304df62 1342
1343 /* Set up any desired flags. */
1344 svp = hv_fetch(action, "FLAGS", 5, FALSE);
1345 act.sa_flags = svp ? SvIV(*svp) : 0;
2304df62 1346
1dfe7606 1347 /* Don't worry about cleaning up *sigsvp if this fails,
1348 * because that means we tried to disposition a
1349 * nonblockable signal, in which case *sigsvp is
1350 * essentially meaningless anyway.
1351 */
6c418a22 1352 RETVAL = sigaction(sig, & act, (struct sigaction *)0);
15c0d34a 1353 if(RETVAL == -1)
1354 XSRETURN_UNDEF;
2304df62 1355 }
1dfe7606 1356
1357 LEAVE;
2304df62 1358 }
6dead956 1359#endif
2304df62 1360 OUTPUT:
1361 RETVAL
1362
1363SysRet
1364sigpending(sigset)
1365 POSIX::SigSet sigset
1366
1367SysRet
1368sigprocmask(how, sigset, oldsigset = 0)
1369 int how
1370 POSIX::SigSet sigset
33c27489 1371 POSIX::SigSet oldsigset = NO_INIT
1372INIT:
1373 if ( items < 3 ) {
1374 oldsigset = 0;
1375 }
1376 else if (sv_derived_from(ST(2), "POSIX::SigSet")) {
1377 IV tmp = SvIV((SV*)SvRV(ST(2)));
56431972 1378 oldsigset = INT2PTR(POSIX__SigSet,tmp);
33c27489 1379 }
1380 else {
01667c76 1381 New(0, oldsigset, 1, sigset_t);
33c27489 1382 sigemptyset(oldsigset);
1383 sv_setref_pv(ST(2), "POSIX::SigSet", (void*)oldsigset);
1384 }
2304df62 1385
1386SysRet
1387sigsuspend(signal_mask)
1388 POSIX::SigSet signal_mask
1389
2304df62 1390void
1391_exit(status)
1392 int status
8990e307 1393
85e6fe83 1394SysRet
8990e307 1395close(fd)
1396 int fd
1397
85e6fe83 1398SysRet
8990e307 1399dup(fd)
1400 int fd
1401
85e6fe83 1402SysRet
8990e307 1403dup2(fd1, fd2)
1404 int fd1
1405 int fd2
1406
4a9d6100 1407SV *
a0d0e21e 1408lseek(fd, offset, whence)
85e6fe83 1409 int fd
1410 Off_t offset
1411 int whence
4a9d6100 1412 CODE:
1413 Off_t pos = PerlLIO_lseek(fd, offset, whence);
1414 RETVAL = sizeof(Off_t) > sizeof(IV)
1415 ? newSVnv((NV)pos) : newSViv((IV)pos);
1416 OUTPUT:
1417 RETVAL
8990e307 1418
c5661c80 1419void
8990e307 1420nice(incr)
1421 int incr
15f0f28a 1422 PPCODE:
1423 errno = 0;
1424 if ((incr = nice(incr)) != -1 || errno == 0) {
1425 if (incr == 0)
1426 XPUSHs(sv_2mortal(newSVpvn("0 but true", 10)));
1427 else
1428 XPUSHs(sv_2mortal(newSViv(incr)));
1429 }
8990e307 1430
8063af02 1431void
8990e307 1432pipe()
85e6fe83 1433 PPCODE:
1434 int fds[2];
85e6fe83 1435 if (pipe(fds) != -1) {
924508f0 1436 EXTEND(SP,2);
85e6fe83 1437 PUSHs(sv_2mortal(newSViv(fds[0])));
1438 PUSHs(sv_2mortal(newSViv(fds[1])));
1439 }
8990e307 1440
85e6fe83 1441SysRet
a0d0e21e 1442read(fd, buffer, nbytes)
7747499c 1443 PREINIT:
1444 SV *sv_buffer = SvROK(ST(1)) ? SvRV(ST(1)) : ST(1);
1445 INPUT:
1446 int fd
1447 size_t nbytes
1448 char * buffer = sv_grow( sv_buffer, nbytes+1 );
a0d0e21e 1449 CLEANUP:
7747499c 1450 if (RETVAL >= 0) {
1451 SvCUR(sv_buffer) = RETVAL;
1452 SvPOK_only(sv_buffer);
1453 *SvEND(sv_buffer) = '\0';
bbce6d69 1454 SvTAINTED_on(sv_buffer);
7747499c 1455 }
8990e307 1456
85e6fe83 1457SysRet
8990e307 1458setpgid(pid, pgid)
86200d5c 1459 pid_t pid
1460 pid_t pgid
8990e307 1461
86200d5c 1462pid_t
8990e307 1463setsid()
1464
86200d5c 1465pid_t
8990e307 1466tcgetpgrp(fd)
1467 int fd
1468
85e6fe83 1469SysRet
8990e307 1470tcsetpgrp(fd, pgrp_id)
1471 int fd
86200d5c 1472 pid_t pgrp_id
8990e307 1473
8063af02 1474void
8990e307 1475uname()
2304df62 1476 PPCODE:
a0d0e21e 1477#ifdef HAS_UNAME
85e6fe83 1478 struct utsname buf;
85e6fe83 1479 if (uname(&buf) >= 0) {
924508f0 1480 EXTEND(SP, 5);
85e6fe83 1481 PUSHs(sv_2mortal(newSVpv(buf.sysname, 0)));
1482 PUSHs(sv_2mortal(newSVpv(buf.nodename, 0)));
1483 PUSHs(sv_2mortal(newSVpv(buf.release, 0)));
1484 PUSHs(sv_2mortal(newSVpv(buf.version, 0)));
1485 PUSHs(sv_2mortal(newSVpv(buf.machine, 0)));
8990e307 1486 }
a0d0e21e 1487#else
1488 uname((char *) 0); /* A stub to call not_here(). */
1489#endif
8990e307 1490
85e6fe83 1491SysRet
a0d0e21e 1492write(fd, buffer, nbytes)
1493 int fd
1494 char * buffer
1495 size_t nbytes
1496
33f01dd1 1497SV *
1498tmpnam()
1499 PREINIT:
1500 STRLEN i;
1501 int len;
1502 CODE:
1503 RETVAL = newSVpvn("", 0);
1504 SvGROW(RETVAL, L_tmpnam);
1505 len = strlen(tmpnam(SvPV(RETVAL, i)));
1506 SvCUR_set(RETVAL, len);
1507 OUTPUT:
1508 RETVAL
a0d0e21e 1509
1510void
1511abort()
1512
1513int
1514mblen(s, n)
1515 char * s
1516 size_t n
1517
1518size_t
1519mbstowcs(s, pwcs, n)
1520 wchar_t * s
1521 char * pwcs
1522 size_t n
1523
1524int
1525mbtowc(pwc, s, n)
1526 wchar_t * pwc
1527 char * s
1528 size_t n
1529
1530int
1531wcstombs(s, pwcs, n)
1532 char * s
1533 wchar_t * pwcs
1534 size_t n
1535
1536int
1537wctomb(s, wchar)
1538 char * s
1539 wchar_t wchar
1540
1541int
1542strcoll(s1, s2)
1543 char * s1
1544 char * s2
1545
a89d8a78 1546void
1547strtod(str)
1548 char * str
1549 PREINIT:
1550 double num;
1551 char *unparsed;
1552 PPCODE:
36477c24 1553 SET_NUMERIC_LOCAL();
a89d8a78 1554 num = strtod(str, &unparsed);
1555 PUSHs(sv_2mortal(newSVnv(num)));
1556 if (GIMME == G_ARRAY) {
924508f0 1557 EXTEND(SP, 1);
a89d8a78 1558 if (unparsed)
1559 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
1560 else
6b88bc9c 1561 PUSHs(&PL_sv_undef);
a89d8a78 1562 }
1563
1564void
1565strtol(str, base = 0)
1566 char * str
1567 int base
1568 PREINIT:
1569 long num;
1570 char *unparsed;
1571 PPCODE:
1572 num = strtol(str, &unparsed, base);
42718184 1573#if IVSIZE <= LONGSIZE
1574 if (num < IV_MIN || num > IV_MAX)
a89d8a78 1575 PUSHs(sv_2mortal(newSVnv((double)num)));
42718184 1576 else
1577#endif
1578 PUSHs(sv_2mortal(newSViv((IV)num)));
a89d8a78 1579 if (GIMME == G_ARRAY) {
924508f0 1580 EXTEND(SP, 1);
a89d8a78 1581 if (unparsed)
1582 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
1583 else
6b88bc9c 1584 PUSHs(&PL_sv_undef);
a89d8a78 1585 }
1586
1587void
1588strtoul(str, base = 0)
1589 char * str
1590 int base
1591 PREINIT:
1592 unsigned long num;
1593 char *unparsed;
1594 PPCODE:
1595 num = strtoul(str, &unparsed, base);
84c133a0 1596#if IVSIZE <= LONGSIZE
1597 if (num > IV_MAX)
a89d8a78 1598 PUSHs(sv_2mortal(newSVnv((double)num)));
84c133a0 1599 else
1600#endif
1601 PUSHs(sv_2mortal(newSViv((IV)num)));
a89d8a78 1602 if (GIMME == G_ARRAY) {
924508f0 1603 EXTEND(SP, 1);
a89d8a78 1604 if (unparsed)
1605 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
1606 else
6b88bc9c 1607 PUSHs(&PL_sv_undef);
a89d8a78 1608 }
1609
8063af02 1610void
a0d0e21e 1611strxfrm(src)
1612 SV * src
85e6fe83 1613 CODE:
a0d0e21e 1614 {
1615 STRLEN srclen;
1616 STRLEN dstlen;
1617 char *p = SvPV(src,srclen);
1618 srclen++;
37cda61e 1619 ST(0) = sv_2mortal(NEWSV(800,srclen*4+1));
a0d0e21e 1620 dstlen = strxfrm(SvPVX(ST(0)), p, (size_t)srclen);
1621 if (dstlen > srclen) {
1622 dstlen++;
1623 SvGROW(ST(0), dstlen);
1624 strxfrm(SvPVX(ST(0)), p, (size_t)dstlen);
1625 dstlen--;
1626 }
1627 SvCUR(ST(0)) = dstlen;
1628 SvPOK_only(ST(0));
1629 }
1630
1631SysRet
1632mkfifo(filename, mode)
1633 char * filename
1634 Mode_t mode
748a9306 1635 CODE:
1636 TAINT_PROPER("mkfifo");
1637 RETVAL = mkfifo(filename, mode);
1638 OUTPUT:
1639 RETVAL
a0d0e21e 1640
1641SysRet
1642tcdrain(fd)
1643 int fd
1644
1645
1646SysRet
1647tcflow(fd, action)
1648 int fd
1649 int action
1650
1651
1652SysRet
1653tcflush(fd, queue_selector)
1654 int fd
1655 int queue_selector
1656
1657SysRet
1658tcsendbreak(fd, duration)
1659 int fd
1660 int duration
1661
1662char *
1663asctime(sec, min, hour, mday, mon, year, wday = 0, yday = 0, isdst = 0)
1664 int sec
1665 int min
1666 int hour
1667 int mday
1668 int mon
1669 int year
1670 int wday
1671 int yday
1672 int isdst
1673 CODE:
1674 {
1675 struct tm mytm;
7747499c 1676 init_tm(&mytm); /* XXX workaround - see init_tm() above */
a0d0e21e 1677 mytm.tm_sec = sec;
1678 mytm.tm_min = min;
1679 mytm.tm_hour = hour;
1680 mytm.tm_mday = mday;
1681 mytm.tm_mon = mon;
1682 mytm.tm_year = year;
1683 mytm.tm_wday = wday;
1684 mytm.tm_yday = yday;
1685 mytm.tm_isdst = isdst;
1686 RETVAL = asctime(&mytm);
1687 }
1688 OUTPUT:
1689 RETVAL
1690
1691long
1692clock()
1693
1694char *
1695ctime(time)
748a9306 1696 Time_t &time
8990e307 1697
37120919 1698void
1699times()
1700 PPCODE:
1701 struct tms tms;
1702 clock_t realtime;
1703 realtime = times( &tms );
924508f0 1704 EXTEND(SP,5);
9607fc9c 1705 PUSHs( sv_2mortal( newSViv( (IV) realtime ) ) );
1706 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_utime ) ) );
1707 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_stime ) ) );
1708 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_cutime ) ) );
1709 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_cstime ) ) );
37120919 1710
a0d0e21e 1711double
1712difftime(time1, time2)
1713 Time_t time1
1714 Time_t time2
1715
1716SysRetLong
1717mktime(sec, min, hour, mday, mon, year, wday = 0, yday = 0, isdst = 0)
1718 int sec
1719 int min
1720 int hour
1721 int mday
1722 int mon
1723 int year
1724 int wday
1725 int yday
1726 int isdst
1727 CODE:
1728 {
1729 struct tm mytm;
7747499c 1730 init_tm(&mytm); /* XXX workaround - see init_tm() above */
a0d0e21e 1731 mytm.tm_sec = sec;
1732 mytm.tm_min = min;
1733 mytm.tm_hour = hour;
1734 mytm.tm_mday = mday;
1735 mytm.tm_mon = mon;
1736 mytm.tm_year = year;
1737 mytm.tm_wday = wday;
1738 mytm.tm_yday = yday;
1739 mytm.tm_isdst = isdst;
1740 RETVAL = mktime(&mytm);
1741 }
85e6fe83 1742 OUTPUT:
1743 RETVAL
a0d0e21e 1744
8063af02 1745#XXX: if $xsubpp::WantOptimize is always the default
1746# sv_setpv(TARG, ...) could be used rather than
1747# ST(0) = sv_2mortal(newSVpv(...))
1748void
e44f695e 1749strftime(fmt, sec, min, hour, mday, mon, year, wday = -1, yday = -1, isdst = -1)
a0d0e21e 1750 char * fmt
1751 int sec
1752 int min
1753 int hour
1754 int mday
1755 int mon
1756 int year
1757 int wday
1758 int yday
1759 int isdst
1760 CODE:
1761 {
b3c85772 1762 char *buf = my_strftime(fmt, sec, min, hour, mday, mon, year, wday, yday, isdst);
2a74cb2d 1763 if (buf) {
1764 ST(0) = sv_2mortal(newSVpv(buf, 0));
bf8afc63 1765 Safefree(buf);
2a74cb2d 1766 }
a0d0e21e 1767 }
1768
1769void
1770tzset()
1771
1772void
1773tzname()
1774 PPCODE:
924508f0 1775 EXTEND(SP,2);
79cb57f6 1776 PUSHs(sv_2mortal(newSVpvn(tzname[0],strlen(tzname[0]))));
1777 PUSHs(sv_2mortal(newSVpvn(tzname[1],strlen(tzname[1]))));
a0d0e21e 1778
1779SysRet
1780access(filename, mode)
1781 char * filename
1782 Mode_t mode
1783
1784char *
1785ctermid(s = 0)
1786 char * s = 0;
1787
1788char *
1789cuserid(s = 0)
1790 char * s = 0;
1791
1792SysRetLong
1793fpathconf(fd, name)
1794 int fd
1795 int name
1796
1797SysRetLong
1798pathconf(filename, name)
1799 char * filename
1800 int name
1801
1802SysRet
1803pause()
1804
a043a685 1805SysRet
1806setgid(gid)
1807 Gid_t gid
1808
1809SysRet
1810setuid(uid)
1811 Uid_t uid
1812
a0d0e21e 1813SysRetLong
1814sysconf(name)
1815 int name
1816
1817char *
1818ttyname(fd)
1819 int fd
a043a685 1820
c6c619a9 1821void
b5846a0b 1822getcwd()
8f95b30d 1823 PPCODE:
1824 {
1825 dXSTARG;
89423764 1826 getcwd_sv(TARG);
8f95b30d 1827 XSprePUSH; PUSHTARG;
1828 }
1829