Re: [perl #24554] Segfault in POSIX module
[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)
767bb2e0 845 SV * charstring
846 PREINIT:
847 STRLEN len;
2304df62 848 CODE:
767bb2e0 849 unsigned char *s = (unsigned char *) SvPV(charstring, len);
850 unsigned char *e = s + len;
5344da4e 851 for (RETVAL = 1; RETVAL && s < e; s++)
2304df62 852 if (!isalnum(*s))
853 RETVAL = 0;
854 OUTPUT:
855 RETVAL
856
857int
858isalpha(charstring)
767bb2e0 859 SV * charstring
860 PREINIT:
861 STRLEN len;
2304df62 862 CODE:
767bb2e0 863 unsigned char *s = (unsigned char *) SvPV(charstring, len);
864 unsigned char *e = s + len;
5344da4e 865 for (RETVAL = 1; RETVAL && s < e; s++)
2304df62 866 if (!isalpha(*s))
867 RETVAL = 0;
868 OUTPUT:
869 RETVAL
870
871int
872iscntrl(charstring)
767bb2e0 873 SV * charstring
874 PREINIT:
875 STRLEN len;
2304df62 876 CODE:
767bb2e0 877 unsigned char *s = (unsigned char *) SvPV(charstring, len);
878 unsigned char *e = s + len;
5344da4e 879 for (RETVAL = 1; RETVAL && s < e; s++)
2304df62 880 if (!iscntrl(*s))
881 RETVAL = 0;
882 OUTPUT:
883 RETVAL
884
885int
886isdigit(charstring)
767bb2e0 887 SV * charstring
888 PREINIT:
889 STRLEN len;
2304df62 890 CODE:
767bb2e0 891 unsigned char *s = (unsigned char *) SvPV(charstring, len);
892 unsigned char *e = s + len;
5344da4e 893 for (RETVAL = 1; RETVAL && s < e; s++)
2304df62 894 if (!isdigit(*s))
895 RETVAL = 0;
896 OUTPUT:
897 RETVAL
898
899int
900isgraph(charstring)
767bb2e0 901 SV * charstring
902 PREINIT:
903 STRLEN len;
2304df62 904 CODE:
767bb2e0 905 unsigned char *s = (unsigned char *) SvPV(charstring, len);
906 unsigned char *e = s + len;
5344da4e 907 for (RETVAL = 1; RETVAL && s < e; s++)
2304df62 908 if (!isgraph(*s))
909 RETVAL = 0;
910 OUTPUT:
911 RETVAL
912
913int
914islower(charstring)
767bb2e0 915 SV * charstring
916 PREINIT:
917 STRLEN len;
2304df62 918 CODE:
767bb2e0 919 unsigned char *s = (unsigned char *) SvPV(charstring, len);
920 unsigned char *e = s + len;
5344da4e 921 for (RETVAL = 1; RETVAL && s < e; s++)
2304df62 922 if (!islower(*s))
923 RETVAL = 0;
924 OUTPUT:
925 RETVAL
926
927int
928isprint(charstring)
767bb2e0 929 SV * charstring
930 PREINIT:
931 STRLEN len;
2304df62 932 CODE:
767bb2e0 933 unsigned char *s = (unsigned char *) SvPV(charstring, len);
934 unsigned char *e = s + len;
5344da4e 935 for (RETVAL = 1; RETVAL && s < e; s++)
2304df62 936 if (!isprint(*s))
937 RETVAL = 0;
938 OUTPUT:
939 RETVAL
940
941int
942ispunct(charstring)
767bb2e0 943 SV * charstring
944 PREINIT:
945 STRLEN len;
2304df62 946 CODE:
767bb2e0 947 unsigned char *s = (unsigned char *) SvPV(charstring, len);
948 unsigned char *e = s + len;
5344da4e 949 for (RETVAL = 1; RETVAL && s < e; s++)
2304df62 950 if (!ispunct(*s))
951 RETVAL = 0;
952 OUTPUT:
953 RETVAL
954
955int
956isspace(charstring)
767bb2e0 957 SV * charstring
958 PREINIT:
959 STRLEN len;
2304df62 960 CODE:
767bb2e0 961 unsigned char *s = (unsigned char *) SvPV(charstring, len);
962 unsigned char *e = s + len;
5344da4e 963 for (RETVAL = 1; RETVAL && s < e; s++)
2304df62 964 if (!isspace(*s))
965 RETVAL = 0;
966 OUTPUT:
967 RETVAL
8990e307 968
969int
2304df62 970isupper(charstring)
767bb2e0 971 SV * charstring
972 PREINIT:
973 STRLEN len;
2304df62 974 CODE:
767bb2e0 975 unsigned char *s = (unsigned char *) SvPV(charstring, len);
976 unsigned char *e = s + len;
5344da4e 977 for (RETVAL = 1; RETVAL && s < e; s++)
2304df62 978 if (!isupper(*s))
979 RETVAL = 0;
980 OUTPUT:
981 RETVAL
8990e307 982
983int
2304df62 984isxdigit(charstring)
767bb2e0 985 SV * charstring
986 PREINIT:
987 STRLEN len;
2304df62 988 CODE:
767bb2e0 989 unsigned char *s = (unsigned char *) SvPV(charstring, len);
990 unsigned char *e = s + len;
5344da4e 991 for (RETVAL = 1; RETVAL && s < e; s++)
2304df62 992 if (!isxdigit(*s))
993 RETVAL = 0;
994 OUTPUT:
995 RETVAL
996
997SysRet
998open(filename, flags = O_RDONLY, mode = 0666)
999 char * filename
1000 int flags
a0d0e21e 1001 Mode_t mode
748a9306 1002 CODE:
1003 if (flags & (O_APPEND|O_CREAT|O_TRUNC|O_RDWR|O_WRONLY|O_EXCL))
1004 TAINT_PROPER("open");
1005 RETVAL = open(filename, flags, mode);
1006 OUTPUT:
1007 RETVAL
1008
2304df62 1009
1010HV *
1011localeconv()
1012 CODE:
a0d0e21e 1013#ifdef HAS_LOCALECONV
2304df62 1014 struct lconv *lcbuf;
1015 RETVAL = newHV();
8063af02 1016 if ((lcbuf = localeconv())) {
2304df62 1017 /* the strings */
1018 if (lcbuf->decimal_point && *lcbuf->decimal_point)
1019 hv_store(RETVAL, "decimal_point", 13,
1020 newSVpv(lcbuf->decimal_point, 0), 0);
1021 if (lcbuf->thousands_sep && *lcbuf->thousands_sep)
1022 hv_store(RETVAL, "thousands_sep", 13,
1023 newSVpv(lcbuf->thousands_sep, 0), 0);
28e8609d 1024#ifndef NO_LOCALECONV_GROUPING
2304df62 1025 if (lcbuf->grouping && *lcbuf->grouping)
1026 hv_store(RETVAL, "grouping", 8,
1027 newSVpv(lcbuf->grouping, 0), 0);
28e8609d 1028#endif
2304df62 1029 if (lcbuf->int_curr_symbol && *lcbuf->int_curr_symbol)
1030 hv_store(RETVAL, "int_curr_symbol", 15,
1031 newSVpv(lcbuf->int_curr_symbol, 0), 0);
1032 if (lcbuf->currency_symbol && *lcbuf->currency_symbol)
1033 hv_store(RETVAL, "currency_symbol", 15,
1034 newSVpv(lcbuf->currency_symbol, 0), 0);
1035 if (lcbuf->mon_decimal_point && *lcbuf->mon_decimal_point)
1036 hv_store(RETVAL, "mon_decimal_point", 17,
1037 newSVpv(lcbuf->mon_decimal_point, 0), 0);
39e571d4 1038#ifndef NO_LOCALECONV_MON_THOUSANDS_SEP
2304df62 1039 if (lcbuf->mon_thousands_sep && *lcbuf->mon_thousands_sep)
1040 hv_store(RETVAL, "mon_thousands_sep", 17,
1041 newSVpv(lcbuf->mon_thousands_sep, 0), 0);
39e571d4 1042#endif
28e8609d 1043#ifndef NO_LOCALECONV_MON_GROUPING
2304df62 1044 if (lcbuf->mon_grouping && *lcbuf->mon_grouping)
1045 hv_store(RETVAL, "mon_grouping", 12,
1046 newSVpv(lcbuf->mon_grouping, 0), 0);
28e8609d 1047#endif
2304df62 1048 if (lcbuf->positive_sign && *lcbuf->positive_sign)
1049 hv_store(RETVAL, "positive_sign", 13,
1050 newSVpv(lcbuf->positive_sign, 0), 0);
1051 if (lcbuf->negative_sign && *lcbuf->negative_sign)
1052 hv_store(RETVAL, "negative_sign", 13,
1053 newSVpv(lcbuf->negative_sign, 0), 0);
1054 /* the integers */
1055 if (lcbuf->int_frac_digits != CHAR_MAX)
1056 hv_store(RETVAL, "int_frac_digits", 15,
1057 newSViv(lcbuf->int_frac_digits), 0);
1058 if (lcbuf->frac_digits != CHAR_MAX)
1059 hv_store(RETVAL, "frac_digits", 11,
1060 newSViv(lcbuf->frac_digits), 0);
1061 if (lcbuf->p_cs_precedes != CHAR_MAX)
1062 hv_store(RETVAL, "p_cs_precedes", 13,
1063 newSViv(lcbuf->p_cs_precedes), 0);
1064 if (lcbuf->p_sep_by_space != CHAR_MAX)
1065 hv_store(RETVAL, "p_sep_by_space", 14,
1066 newSViv(lcbuf->p_sep_by_space), 0);
1067 if (lcbuf->n_cs_precedes != CHAR_MAX)
1068 hv_store(RETVAL, "n_cs_precedes", 13,
1069 newSViv(lcbuf->n_cs_precedes), 0);
1070 if (lcbuf->n_sep_by_space != CHAR_MAX)
1071 hv_store(RETVAL, "n_sep_by_space", 14,
1072 newSViv(lcbuf->n_sep_by_space), 0);
1073 if (lcbuf->p_sign_posn != CHAR_MAX)
1074 hv_store(RETVAL, "p_sign_posn", 11,
1075 newSViv(lcbuf->p_sign_posn), 0);
1076 if (lcbuf->n_sign_posn != CHAR_MAX)
1077 hv_store(RETVAL, "n_sign_posn", 11,
1078 newSViv(lcbuf->n_sign_posn), 0);
1079 }
a0d0e21e 1080#else
1081 localeconv(); /* A stub to call not_here(). */
1082#endif
2304df62 1083 OUTPUT:
1084 RETVAL
1085
1086char *
c28ee57b 1087setlocale(category, locale = 0)
2304df62 1088 int category
1089 char * locale
c28ee57b 1090 CODE:
1091 RETVAL = setlocale(category, locale);
bbce6d69 1092 if (RETVAL) {
36477c24 1093#ifdef USE_LOCALE_CTYPE
bbce6d69 1094 if (category == LC_CTYPE
1095#ifdef LC_ALL
1096 || category == LC_ALL
1097#endif
1098 )
1099 {
1100 char *newctype;
1101#ifdef LC_ALL
1102 if (category == LC_ALL)
1103 newctype = setlocale(LC_CTYPE, NULL);
1104 else
1105#endif
1106 newctype = RETVAL;
864dbfa3 1107 new_ctype(newctype);
bbce6d69 1108 }
36477c24 1109#endif /* USE_LOCALE_CTYPE */
1110#ifdef USE_LOCALE_COLLATE
bbce6d69 1111 if (category == LC_COLLATE
1112#ifdef LC_ALL
1113 || category == LC_ALL
1114#endif
1115 )
1116 {
1117 char *newcoll;
1118#ifdef LC_ALL
1119 if (category == LC_ALL)
1120 newcoll = setlocale(LC_COLLATE, NULL);
1121 else
1122#endif
1123 newcoll = RETVAL;
864dbfa3 1124 new_collate(newcoll);
bbce6d69 1125 }
36477c24 1126#endif /* USE_LOCALE_COLLATE */
1127#ifdef USE_LOCALE_NUMERIC
bbce6d69 1128 if (category == LC_NUMERIC
1129#ifdef LC_ALL
1130 || category == LC_ALL
1131#endif
1132 )
1133 {
1134 char *newnum;
1135#ifdef LC_ALL
1136 if (category == LC_ALL)
1137 newnum = setlocale(LC_NUMERIC, NULL);
1138 else
1139#endif
1140 newnum = RETVAL;
864dbfa3 1141 new_numeric(newnum);
bbce6d69 1142 }
36477c24 1143#endif /* USE_LOCALE_NUMERIC */
bbce6d69 1144 }
c28ee57b 1145 OUTPUT:
1146 RETVAL
1147
2304df62 1148
e1ca407b 1149NV
2304df62 1150acos(x)
e1ca407b 1151 NV x
2304df62 1152
e1ca407b 1153NV
2304df62 1154asin(x)
e1ca407b 1155 NV x
2304df62 1156
e1ca407b 1157NV
2304df62 1158atan(x)
e1ca407b 1159 NV x
2304df62 1160
e1ca407b 1161NV
2304df62 1162ceil(x)
e1ca407b 1163 NV x
2304df62 1164
e1ca407b 1165NV
2304df62 1166cosh(x)
e1ca407b 1167 NV x
2304df62 1168
e1ca407b 1169NV
2304df62 1170floor(x)
e1ca407b 1171 NV x
2304df62 1172
e1ca407b 1173NV
2304df62 1174fmod(x,y)
e1ca407b 1175 NV x
1176 NV y
2304df62 1177
1178void
1179frexp(x)
e1ca407b 1180 NV x
2304df62 1181 PPCODE:
1182 int expvar;
2304df62 1183 /* (We already know stack is long enough.) */
1184 PUSHs(sv_2mortal(newSVnv(frexp(x,&expvar))));
1185 PUSHs(sv_2mortal(newSViv(expvar)));
1186
e1ca407b 1187NV
2304df62 1188ldexp(x,exp)
e1ca407b 1189 NV x
2304df62 1190 int exp
1191
e1ca407b 1192NV
2304df62 1193log10(x)
e1ca407b 1194 NV x
2304df62 1195
1196void
1197modf(x)
e1ca407b 1198 NV x
2304df62 1199 PPCODE:
e1ca407b 1200 NV intvar;
2304df62 1201 /* (We already know stack is long enough.) */
bf4acbe4 1202 PUSHs(sv_2mortal(newSVnv(Perl_modf(x,&intvar))));
2304df62 1203 PUSHs(sv_2mortal(newSVnv(intvar)));
1204
e1ca407b 1205NV
2304df62 1206sinh(x)
e1ca407b 1207 NV x
2304df62 1208
e1ca407b 1209NV
3b35bae3 1210tan(x)
e1ca407b 1211 NV x
3b35bae3 1212
e1ca407b 1213NV
2304df62 1214tanh(x)
e1ca407b 1215 NV x
2304df62 1216
1217SysRet
1dfe7606 1218sigaction(sig, optaction, oldaction = 0)
2304df62 1219 int sig
1dfe7606 1220 SV * optaction
2304df62 1221 POSIX::SigAction oldaction
1222 CODE:
2986a63f 1223#if defined(WIN32) || defined(NETWARE)
6dead956 1224 RETVAL = not_here("sigaction");
1225#else
2304df62 1226# This code is really grody because we're trying to make the signal
1227# interface look beautiful, which is hard.
1228
2304df62 1229 {
1dfe7606 1230 POSIX__SigAction action;
f4c556ac 1231 GV *siggv = gv_fetchpv("SIG", TRUE, SVt_PVHV);
2304df62 1232 struct sigaction act;
1233 struct sigaction oact;
1dfe7606 1234 sigset_t sset;
183bde56 1235 SV *osset_sv;
27c1a449 1236 sigset_t osset;
2304df62 1237 POSIX__SigSet sigset;
1238 SV** svp;
1d81eac9 1239 SV** sigsvp;
1240 if (sig == 0 && SvPOK(ST(0))) {
1241 char *s = SvPVX(ST(0));
1242 int i = whichsig(s);
1243
1244 if (i < 0 && memEQ(s, "SIG", 3))
1245 i = whichsig(s + 3);
1246 if (i < 0) {
1247 if (ckWARN(WARN_SIGNAL))
1248 Perl_warner(aTHX_ packWARN(WARN_SIGNAL),
1249 "No such signal: SIG%s", s);
1250 XSRETURN_UNDEF;
1251 }
1252 else
1253 sig = i;
1254 }
1255 sigsvp = hv_fetch(GvHVn(siggv),
1256 PL_sig_name[sig],
1257 strlen(PL_sig_name[sig]),
1258 TRUE);
2304df62 1259
1dfe7606 1260 /* Check optaction and set action */
1261 if(SvTRUE(optaction)) {
1262 if(sv_isa(optaction, "POSIX::SigAction"))
1263 action = (HV*)SvRV(optaction);
1264 else
1265 croak("action is not of type POSIX::SigAction");
1266 }
1267 else {
1268 action=0;
1269 }
1270
1271 /* sigaction() is supposed to look atomic. In particular, any
1272 * signal handler invoked during a sigaction() call should
1273 * see either the old or the new disposition, and not something
1274 * in between. We use sigprocmask() to make it so.
1275 */
1276 sigfillset(&sset);
1277 RETVAL=sigprocmask(SIG_BLOCK, &sset, &osset);
1278 if(RETVAL == -1)
15c0d34a 1279 XSRETURN_UNDEF;
1dfe7606 1280 ENTER;
1281 /* Restore signal mask no matter how we exit this block. */
183bde56 1282 osset_sv = newSVpv((char *)(&osset), sizeof(sigset_t));
1283 SAVEFREESV( osset_sv );
40b7a5f5 1284 SAVEDESTRUCTOR_X(restore_sigmask, osset_sv);
1dfe7606 1285
1286 RETVAL=-1; /* In case both oldaction and action are 0. */
1287
1288 /* Remember old disposition if desired. */
2304df62 1289 if (oldaction) {
2304df62 1290 svp = hv_fetch(oldaction, "HANDLER", 7, TRUE);
1dfe7606 1291 if(!svp)
1292 croak("Can't supply an oldaction without a HANDLER");
1293 if(SvTRUE(*sigsvp)) { /* TBD: what if "0"? */
1294 sv_setsv(*svp, *sigsvp);
1295 }
1296 else {
1297 sv_setpv(*svp, "DEFAULT");
1298 }
1299 RETVAL = sigaction(sig, (struct sigaction *)0, & oact);
1300 if(RETVAL == -1)
15c0d34a 1301 XSRETURN_UNDEF;
1dfe7606 1302 /* Get back the mask. */
1303 svp = hv_fetch(oldaction, "MASK", 4, TRUE);
1304 if (sv_isa(*svp, "POSIX::SigSet")) {
1305 IV tmp = SvIV((SV*)SvRV(*svp));
1306 sigset = INT2PTR(sigset_t*, tmp);
1307 }
1308 else {
1309 New(0, sigset, 1, sigset_t);
1310 sv_setptrobj(*svp, sigset, "POSIX::SigSet");
1311 }
1312 *sigset = oact.sa_mask;
1313
1314 /* Get back the flags. */
1315 svp = hv_fetch(oldaction, "FLAGS", 5, TRUE);
1316 sv_setiv(*svp, oact.sa_flags);
d36b6582 1317
1318 /* Get back whether the old handler used safe signals. */
1319 svp = hv_fetch(oldaction, "SAFE", 4, TRUE);
5c1546dc 1320 sv_setiv(*svp, oact.sa_handler == PL_csighandlerp);
2304df62 1321 }
1322
1323 if (action) {
d36b6582 1324 /* Safe signals use "csighandler", which vectors through the
1325 PL_sighandlerp pointer when it's safe to do so.
1326 (BTW, "csighandler" is very different from "sighandler".) */
1327 svp = hv_fetch(action, "SAFE", 4, FALSE);
1328 act.sa_handler = (*svp && SvTRUE(*svp))
b4ed63f0 1329 ? PL_csighandlerp : PL_sighandlerp;
d36b6582 1330
1331 /* Vector new Perl handler through %SIG.
1332 (The core signal handlers read %SIG to dispatch.) */
2304df62 1333 svp = hv_fetch(action, "HANDLER", 7, FALSE);
1334 if (!svp)
1335 croak("Can't supply an action without a HANDLER");
1dfe7606 1336 sv_setsv(*sigsvp, *svp);
d36b6582 1337
1338 /* This call actually calls sigaction() with almost the
1339 right settings, including appropriate interpretation
1340 of DEFAULT and IGNORE. However, why are we doing
1341 this when we're about to do it again just below? XXX */
1342 mg_set(*sigsvp);
1343
1344 /* And here again we duplicate -- DEFAULT/IGNORE checking. */
1dfe7606 1345 if(SvPOK(*svp)) {
1346 char *s=SvPVX(*svp);
1347 if(strEQ(s,"IGNORE")) {
1348 act.sa_handler = SIG_IGN;
1349 }
1350 else if(strEQ(s,"DEFAULT")) {
1351 act.sa_handler = SIG_DFL;
1352 }
1dfe7606 1353 }
2304df62 1354
1355 /* Set up any desired mask. */
1356 svp = hv_fetch(action, "MASK", 4, FALSE);
1357 if (svp && sv_isa(*svp, "POSIX::SigSet")) {
ac634a9a 1358 IV tmp = SvIV((SV*)SvRV(*svp));
1dfe7606 1359 sigset = INT2PTR(sigset_t*, tmp);
2304df62 1360 act.sa_mask = *sigset;
1361 }
1362 else
85e6fe83 1363 sigemptyset(& act.sa_mask);
2304df62 1364
1365 /* Set up any desired flags. */
1366 svp = hv_fetch(action, "FLAGS", 5, FALSE);
1367 act.sa_flags = svp ? SvIV(*svp) : 0;
2304df62 1368
1dfe7606 1369 /* Don't worry about cleaning up *sigsvp if this fails,
1370 * because that means we tried to disposition a
1371 * nonblockable signal, in which case *sigsvp is
1372 * essentially meaningless anyway.
1373 */
6c418a22 1374 RETVAL = sigaction(sig, & act, (struct sigaction *)0);
15c0d34a 1375 if(RETVAL == -1)
1376 XSRETURN_UNDEF;
2304df62 1377 }
1dfe7606 1378
1379 LEAVE;
2304df62 1380 }
6dead956 1381#endif
2304df62 1382 OUTPUT:
1383 RETVAL
1384
1385SysRet
1386sigpending(sigset)
1387 POSIX::SigSet sigset
1388
1389SysRet
1390sigprocmask(how, sigset, oldsigset = 0)
1391 int how
1392 POSIX::SigSet sigset
33c27489 1393 POSIX::SigSet oldsigset = NO_INIT
1394INIT:
1395 if ( items < 3 ) {
1396 oldsigset = 0;
1397 }
1398 else if (sv_derived_from(ST(2), "POSIX::SigSet")) {
1399 IV tmp = SvIV((SV*)SvRV(ST(2)));
56431972 1400 oldsigset = INT2PTR(POSIX__SigSet,tmp);
33c27489 1401 }
1402 else {
01667c76 1403 New(0, oldsigset, 1, sigset_t);
33c27489 1404 sigemptyset(oldsigset);
1405 sv_setref_pv(ST(2), "POSIX::SigSet", (void*)oldsigset);
1406 }
2304df62 1407
1408SysRet
1409sigsuspend(signal_mask)
1410 POSIX::SigSet signal_mask
1411
2304df62 1412void
1413_exit(status)
1414 int status
8990e307 1415
85e6fe83 1416SysRet
8990e307 1417close(fd)
1418 int fd
1419
85e6fe83 1420SysRet
8990e307 1421dup(fd)
1422 int fd
1423
85e6fe83 1424SysRet
8990e307 1425dup2(fd1, fd2)
1426 int fd1
1427 int fd2
1428
4a9d6100 1429SV *
a0d0e21e 1430lseek(fd, offset, whence)
85e6fe83 1431 int fd
1432 Off_t offset
1433 int whence
4a9d6100 1434 CODE:
1435 Off_t pos = PerlLIO_lseek(fd, offset, whence);
1436 RETVAL = sizeof(Off_t) > sizeof(IV)
1437 ? newSVnv((NV)pos) : newSViv((IV)pos);
1438 OUTPUT:
1439 RETVAL
8990e307 1440
c5661c80 1441void
8990e307 1442nice(incr)
1443 int incr
15f0f28a 1444 PPCODE:
1445 errno = 0;
1446 if ((incr = nice(incr)) != -1 || errno == 0) {
1447 if (incr == 0)
1448 XPUSHs(sv_2mortal(newSVpvn("0 but true", 10)));
1449 else
1450 XPUSHs(sv_2mortal(newSViv(incr)));
1451 }
8990e307 1452
8063af02 1453void
8990e307 1454pipe()
85e6fe83 1455 PPCODE:
1456 int fds[2];
85e6fe83 1457 if (pipe(fds) != -1) {
924508f0 1458 EXTEND(SP,2);
85e6fe83 1459 PUSHs(sv_2mortal(newSViv(fds[0])));
1460 PUSHs(sv_2mortal(newSViv(fds[1])));
1461 }
8990e307 1462
85e6fe83 1463SysRet
a0d0e21e 1464read(fd, buffer, nbytes)
7747499c 1465 PREINIT:
1466 SV *sv_buffer = SvROK(ST(1)) ? SvRV(ST(1)) : ST(1);
1467 INPUT:
1468 int fd
1469 size_t nbytes
1470 char * buffer = sv_grow( sv_buffer, nbytes+1 );
a0d0e21e 1471 CLEANUP:
7747499c 1472 if (RETVAL >= 0) {
1473 SvCUR(sv_buffer) = RETVAL;
1474 SvPOK_only(sv_buffer);
1475 *SvEND(sv_buffer) = '\0';
bbce6d69 1476 SvTAINTED_on(sv_buffer);
7747499c 1477 }
8990e307 1478
85e6fe83 1479SysRet
8990e307 1480setpgid(pid, pgid)
86200d5c 1481 pid_t pid
1482 pid_t pgid
8990e307 1483
86200d5c 1484pid_t
8990e307 1485setsid()
1486
86200d5c 1487pid_t
8990e307 1488tcgetpgrp(fd)
1489 int fd
1490
85e6fe83 1491SysRet
8990e307 1492tcsetpgrp(fd, pgrp_id)
1493 int fd
86200d5c 1494 pid_t pgrp_id
8990e307 1495
8063af02 1496void
8990e307 1497uname()
2304df62 1498 PPCODE:
a0d0e21e 1499#ifdef HAS_UNAME
85e6fe83 1500 struct utsname buf;
85e6fe83 1501 if (uname(&buf) >= 0) {
924508f0 1502 EXTEND(SP, 5);
85e6fe83 1503 PUSHs(sv_2mortal(newSVpv(buf.sysname, 0)));
1504 PUSHs(sv_2mortal(newSVpv(buf.nodename, 0)));
1505 PUSHs(sv_2mortal(newSVpv(buf.release, 0)));
1506 PUSHs(sv_2mortal(newSVpv(buf.version, 0)));
1507 PUSHs(sv_2mortal(newSVpv(buf.machine, 0)));
8990e307 1508 }
a0d0e21e 1509#else
1510 uname((char *) 0); /* A stub to call not_here(). */
1511#endif
8990e307 1512
85e6fe83 1513SysRet
a0d0e21e 1514write(fd, buffer, nbytes)
1515 int fd
1516 char * buffer
1517 size_t nbytes
1518
33f01dd1 1519SV *
1520tmpnam()
1521 PREINIT:
1522 STRLEN i;
1523 int len;
1524 CODE:
1525 RETVAL = newSVpvn("", 0);
1526 SvGROW(RETVAL, L_tmpnam);
1527 len = strlen(tmpnam(SvPV(RETVAL, i)));
1528 SvCUR_set(RETVAL, len);
1529 OUTPUT:
1530 RETVAL
a0d0e21e 1531
1532void
1533abort()
1534
1535int
1536mblen(s, n)
1537 char * s
1538 size_t n
1539
1540size_t
1541mbstowcs(s, pwcs, n)
1542 wchar_t * s
1543 char * pwcs
1544 size_t n
1545
1546int
1547mbtowc(pwc, s, n)
1548 wchar_t * pwc
1549 char * s
1550 size_t n
1551
1552int
1553wcstombs(s, pwcs, n)
1554 char * s
1555 wchar_t * pwcs
1556 size_t n
1557
1558int
1559wctomb(s, wchar)
1560 char * s
1561 wchar_t wchar
1562
1563int
1564strcoll(s1, s2)
1565 char * s1
1566 char * s2
1567
a89d8a78 1568void
1569strtod(str)
1570 char * str
1571 PREINIT:
1572 double num;
1573 char *unparsed;
1574 PPCODE:
36477c24 1575 SET_NUMERIC_LOCAL();
a89d8a78 1576 num = strtod(str, &unparsed);
1577 PUSHs(sv_2mortal(newSVnv(num)));
1578 if (GIMME == G_ARRAY) {
924508f0 1579 EXTEND(SP, 1);
a89d8a78 1580 if (unparsed)
1581 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
1582 else
6b88bc9c 1583 PUSHs(&PL_sv_undef);
a89d8a78 1584 }
1585
1586void
1587strtol(str, base = 0)
1588 char * str
1589 int base
1590 PREINIT:
1591 long num;
1592 char *unparsed;
1593 PPCODE:
1594 num = strtol(str, &unparsed, base);
42718184 1595#if IVSIZE <= LONGSIZE
1596 if (num < IV_MIN || num > IV_MAX)
a89d8a78 1597 PUSHs(sv_2mortal(newSVnv((double)num)));
42718184 1598 else
1599#endif
1600 PUSHs(sv_2mortal(newSViv((IV)num)));
a89d8a78 1601 if (GIMME == G_ARRAY) {
924508f0 1602 EXTEND(SP, 1);
a89d8a78 1603 if (unparsed)
1604 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
1605 else
6b88bc9c 1606 PUSHs(&PL_sv_undef);
a89d8a78 1607 }
1608
1609void
1610strtoul(str, base = 0)
1611 char * str
1612 int base
1613 PREINIT:
1614 unsigned long num;
1615 char *unparsed;
1616 PPCODE:
1617 num = strtoul(str, &unparsed, base);
84c133a0 1618#if IVSIZE <= LONGSIZE
1619 if (num > IV_MAX)
a89d8a78 1620 PUSHs(sv_2mortal(newSVnv((double)num)));
84c133a0 1621 else
1622#endif
1623 PUSHs(sv_2mortal(newSViv((IV)num)));
a89d8a78 1624 if (GIMME == G_ARRAY) {
924508f0 1625 EXTEND(SP, 1);
a89d8a78 1626 if (unparsed)
1627 PUSHs(sv_2mortal(newSViv(strlen(unparsed))));
1628 else
6b88bc9c 1629 PUSHs(&PL_sv_undef);
a89d8a78 1630 }
1631
8063af02 1632void
a0d0e21e 1633strxfrm(src)
1634 SV * src
85e6fe83 1635 CODE:
a0d0e21e 1636 {
1637 STRLEN srclen;
1638 STRLEN dstlen;
1639 char *p = SvPV(src,srclen);
1640 srclen++;
37cda61e 1641 ST(0) = sv_2mortal(NEWSV(800,srclen*4+1));
a0d0e21e 1642 dstlen = strxfrm(SvPVX(ST(0)), p, (size_t)srclen);
1643 if (dstlen > srclen) {
1644 dstlen++;
1645 SvGROW(ST(0), dstlen);
1646 strxfrm(SvPVX(ST(0)), p, (size_t)dstlen);
1647 dstlen--;
1648 }
1649 SvCUR(ST(0)) = dstlen;
1650 SvPOK_only(ST(0));
1651 }
1652
1653SysRet
1654mkfifo(filename, mode)
1655 char * filename
1656 Mode_t mode
748a9306 1657 CODE:
1658 TAINT_PROPER("mkfifo");
1659 RETVAL = mkfifo(filename, mode);
1660 OUTPUT:
1661 RETVAL
a0d0e21e 1662
1663SysRet
1664tcdrain(fd)
1665 int fd
1666
1667
1668SysRet
1669tcflow(fd, action)
1670 int fd
1671 int action
1672
1673
1674SysRet
1675tcflush(fd, queue_selector)
1676 int fd
1677 int queue_selector
1678
1679SysRet
1680tcsendbreak(fd, duration)
1681 int fd
1682 int duration
1683
1684char *
1685asctime(sec, min, hour, mday, mon, year, wday = 0, yday = 0, isdst = 0)
1686 int sec
1687 int min
1688 int hour
1689 int mday
1690 int mon
1691 int year
1692 int wday
1693 int yday
1694 int isdst
1695 CODE:
1696 {
1697 struct tm mytm;
7747499c 1698 init_tm(&mytm); /* XXX workaround - see init_tm() above */
a0d0e21e 1699 mytm.tm_sec = sec;
1700 mytm.tm_min = min;
1701 mytm.tm_hour = hour;
1702 mytm.tm_mday = mday;
1703 mytm.tm_mon = mon;
1704 mytm.tm_year = year;
1705 mytm.tm_wday = wday;
1706 mytm.tm_yday = yday;
1707 mytm.tm_isdst = isdst;
1708 RETVAL = asctime(&mytm);
1709 }
1710 OUTPUT:
1711 RETVAL
1712
1713long
1714clock()
1715
1716char *
1717ctime(time)
748a9306 1718 Time_t &time
8990e307 1719
37120919 1720void
1721times()
1722 PPCODE:
1723 struct tms tms;
1724 clock_t realtime;
1725 realtime = times( &tms );
924508f0 1726 EXTEND(SP,5);
9607fc9c 1727 PUSHs( sv_2mortal( newSViv( (IV) realtime ) ) );
1728 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_utime ) ) );
1729 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_stime ) ) );
1730 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_cutime ) ) );
1731 PUSHs( sv_2mortal( newSViv( (IV) tms.tms_cstime ) ) );
37120919 1732
a0d0e21e 1733double
1734difftime(time1, time2)
1735 Time_t time1
1736 Time_t time2
1737
1738SysRetLong
1739mktime(sec, min, hour, mday, mon, year, wday = 0, yday = 0, isdst = 0)
1740 int sec
1741 int min
1742 int hour
1743 int mday
1744 int mon
1745 int year
1746 int wday
1747 int yday
1748 int isdst
1749 CODE:
1750 {
1751 struct tm mytm;
7747499c 1752 init_tm(&mytm); /* XXX workaround - see init_tm() above */
a0d0e21e 1753 mytm.tm_sec = sec;
1754 mytm.tm_min = min;
1755 mytm.tm_hour = hour;
1756 mytm.tm_mday = mday;
1757 mytm.tm_mon = mon;
1758 mytm.tm_year = year;
1759 mytm.tm_wday = wday;
1760 mytm.tm_yday = yday;
1761 mytm.tm_isdst = isdst;
1762 RETVAL = mktime(&mytm);
1763 }
85e6fe83 1764 OUTPUT:
1765 RETVAL
a0d0e21e 1766
8063af02 1767#XXX: if $xsubpp::WantOptimize is always the default
1768# sv_setpv(TARG, ...) could be used rather than
1769# ST(0) = sv_2mortal(newSVpv(...))
1770void
e44f695e 1771strftime(fmt, sec, min, hour, mday, mon, year, wday = -1, yday = -1, isdst = -1)
a0d0e21e 1772 char * fmt
1773 int sec
1774 int min
1775 int hour
1776 int mday
1777 int mon
1778 int year
1779 int wday
1780 int yday
1781 int isdst
1782 CODE:
1783 {
b3c85772 1784 char *buf = my_strftime(fmt, sec, min, hour, mday, mon, year, wday, yday, isdst);
2a74cb2d 1785 if (buf) {
1786 ST(0) = sv_2mortal(newSVpv(buf, 0));
bf8afc63 1787 Safefree(buf);
2a74cb2d 1788 }
a0d0e21e 1789 }
1790
1791void
1792tzset()
1793
1794void
1795tzname()
1796 PPCODE:
924508f0 1797 EXTEND(SP,2);
79cb57f6 1798 PUSHs(sv_2mortal(newSVpvn(tzname[0],strlen(tzname[0]))));
1799 PUSHs(sv_2mortal(newSVpvn(tzname[1],strlen(tzname[1]))));
a0d0e21e 1800
1801SysRet
1802access(filename, mode)
1803 char * filename
1804 Mode_t mode
1805
1806char *
1807ctermid(s = 0)
1808 char * s = 0;
1809
1810char *
1811cuserid(s = 0)
1812 char * s = 0;
1813
1814SysRetLong
1815fpathconf(fd, name)
1816 int fd
1817 int name
1818
1819SysRetLong
1820pathconf(filename, name)
1821 char * filename
1822 int name
1823
1824SysRet
1825pause()
1826
a043a685 1827SysRet
1828setgid(gid)
1829 Gid_t gid
1830
1831SysRet
1832setuid(uid)
1833 Uid_t uid
1834
a0d0e21e 1835SysRetLong
1836sysconf(name)
1837 int name
1838
1839char *
1840ttyname(fd)
1841 int fd
a043a685 1842
c6c619a9 1843void
b5846a0b 1844getcwd()
8f95b30d 1845 PPCODE:
1846 {
1847 dXSTARG;
89423764 1848 getcwd_sv(TARG);
8f95b30d 1849 XSprePUSH; PUSHTARG;
1850 }
1851