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