whoami7 - Manager
:
/
root
/
.cpanm
/
latest-build
/
IO-Tty-1.20
/
Upload File:
files >> //root/.cpanm/latest-build/IO-Tty-1.20/Tty.c
/* * This file was generated automatically by ExtUtils::ParseXS version 3.35 from the * contents of Tty.xs. Do not edit this file, edit Tty.xs instead. * * ANY CHANGES MADE HERE WILL BE LOST! * */ #line 1 "Tty.xs" #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #define PTY_DEBUG 1 #ifdef PTY_DEBUG static int print_debug; #endif #ifdef PerlIO typedef int SysRet; typedef PerlIO * InOutStream; #else # define PERLIO_IS_STDIO 1 # define PerlIO_fileno fileno typedef int SysRet; typedef FILE * InOutStream; #endif #include "patchlevel.h" #if (PATCHLEVEL < 3) || ((PATCHLEVEL == 3) && (SUBVERSION < 22)) /* before 5.003_22 */ # define MY_start_subparse(fmt,flags) start_subparse() #else # if (PATCHLEVEL == 3) && (SUBVERSION == 22) /* 5.003_22 */ # define MY_start_subparse(fmt,flags) start_subparse(flags) # else /* 5.003_23 onwards */ # define MY_start_subparse(fmt,flags) start_subparse(fmt,flags) # endif #endif /* * The following pty-allocation code was heavily inspired by its * counterparts in openssh 3.0p1 and Xemacs 21.4.5 but is a complete * rewrite by me, Roland Giersig <RGiersig@cpan.org>. * * Nevertheless my references to Tatu Ylonen <ylo@cs.hut.fi> * and the Xemacs development team for their inspiring code. * * mysignal and strlcpy were borrowed from openssh and have their * copyright messages attached. */ #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/ioctl.h> #ifdef HAVE_LIBUTIL_H # include <libutil.h> #endif /* HAVE_UTIL_H */ #ifdef HAVE_UTIL_H # ifdef UTIL_H_ABS_PATH # include UTIL_H_ABS_PATH # elif ((PATCHLEVEL < 19) || ((PATCHLEVEL == 19) && (SUBVERSION < 4))) # include <util.h> # endif #endif /* HAVE_UTIL_H */ #ifdef HAVE_PTY_H # include <pty.h> #endif #ifdef HAVE_SYS_PTY_H # include <sys/pty.h> #endif #ifdef HAVE_SYS_PTYIO_H # include <sys/ptyio.h> #endif #if defined(HAVE_DEV_PTMX) && defined(HAVE_SYS_STROPTS_H) # include <sys/stropts.h> #endif #ifdef HAVE_TERMIOS_H #include <termios.h> #endif #ifdef HAVE_TERMIO_H #include <termio.h> #endif #ifndef O_NOCTTY #define O_NOCTTY 0 #endif /* from $OpenBSD: misc.c,v 1.12 2001/06/26 17:27:24 markus Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include <signal.h> typedef void (*mysig_t)(int); static mysig_t mysignal(int sig, mysig_t act) { #ifdef HAVE_SIGACTION struct sigaction sa, osa; if (sigaction(sig, NULL, &osa) == -1) return (mysig_t) -1; if (osa.sa_handler != act) { memset(&sa, 0, sizeof(sa)); sigemptyset(&sa.sa_mask); sa.sa_flags = 0; #if defined(SA_INTERRUPT) if (sig == SIGALRM) sa.sa_flags |= SA_INTERRUPT; #endif sa.sa_handler = act; if (sigaction(sig, &sa, NULL) == -1) return (mysig_t) -1; } return (osa.sa_handler); #else return (signal(sig, act)); #endif } /* from $OpenBSD: strlcpy.c,v 1.5 2001/05/13 15:40:16 deraadt Exp $ */ /* * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef HAVE_STRLCPY /* * Copy src to string dst of size siz. At most siz-1 characters * will be copied. Always NUL terminates (unless siz == 0). * Returns strlen(src); if retval >= siz, truncation occurred. */ static size_t strlcpy(dst, src, siz) char *dst; const char *src; size_t siz; { register char *d = dst; register const char *s = src; register size_t n = siz; /* Copy as many bytes as will fit */ if (n != 0 && --n != 0) { do { if ((*d++ = *s++) == 0) break; } while (--n != 0); } /* Not enough room in dst, add NUL and traverse rest of src */ if (n == 0) { if (siz != 0) *d = '\0'; /* NUL-terminate dst */ while (*s++) ; } return(s - src - 1); /* count does not include NUL */ } #endif /* !HAVE_STRLCPY */ /* * Move file descriptor so it doesn't collide with stdin/out/err */ static void make_safe_fd(int * fd) { if (*fd < 3) { int newfd; newfd = fcntl(*fd, F_DUPFD, 3); if (newfd < 0) { if (PL_dowarn) warn("IO::Tty::pty_allocate(nonfatal): tried to move fd %d up but fcntl() said %.100s", *fd, strerror(errno)); } else { close (*fd); *fd = newfd; } } } /* * After having acquired a master pty, try to find out the slave name, * initialize and open the slave. */ #if defined (HAVE_PTSNAME) char * ptsname(int); #endif static int open_slave(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen) { /* * now do some things that are supposedly healthy for ptys, * i.e. changing the access mode. */ #if defined(HAVE_GRANTPT) || defined(HAVE_UNLOCKPT) { mysig_t old_signal; old_signal = mysignal(SIGCHLD, SIG_DFL); #if defined(HAVE_GRANTPT) #if PTY_DEBUG if (print_debug) fprintf(stderr, "trying grantpt()...\n"); #endif if (grantpt(*ptyfd) < 0) { if (PL_dowarn) warn("IO::Tty::pty_allocate(nonfatal): grantpt(): %.100s", strerror(errno)); } #endif /* HAVE_GRANTPT */ #if defined(HAVE_UNLOCKPT) #if PTY_DEBUG if (print_debug) fprintf(stderr, "trying unlockpt()...\n"); #endif if (unlockpt(*ptyfd) < 0) { if (PL_dowarn) warn("IO::Tty::pty_allocate(nonfatal): unlockpt(): %.100s", strerror(errno)); } #endif /* HAVE_UNLOCKPT */ mysignal(SIGCHLD, old_signal); } #endif /* HAVE_GRANTPT || HAVE_UNLOCKPT */ /* * find the slave name, if we don't have it already */ #if defined (HAVE_PTSNAME_R) if (namebuf[0] == 0) { #if PTY_DEBUG if (print_debug) fprintf(stderr, "trying ptsname_r()...\n"); #endif if(ptsname_r(*ptyfd, namebuf, namebuflen)) { if (PL_dowarn) warn("IO::Tty::open_slave(nonfatal): ptsname_r(): %.100s", strerror(errno)); } } #endif /* HAVE_PTSNAME_R */ #if defined (HAVE_PTSNAME) if (namebuf[0] == 0) { char * name; #if PTY_DEBUG if (print_debug) fprintf(stderr, "trying ptsname()...\n"); #endif name = ptsname(*ptyfd); if (name) { if(strlcpy(namebuf, name, namebuflen) >= namebuflen) { warn("ERROR: IO::Tty::open_slave: ttyname truncated"); return 0; } } else { if (PL_dowarn) warn("IO::Tty::open_slave(nonfatal): ptsname(): %.100s", strerror(errno)); } } #endif /* HAVE_PTSNAME */ if (namebuf[0] == 0) return 0; /* we failed to get the slave name */ #if defined (__SVR4) && defined (__sun) #include <sys/types.h> #include <unistd.h> { uid_t euid = geteuid(); uid_t uid = getuid(); /* root running as another user * grantpt() has done the wrong thing */ if (euid != uid && uid == 0) { #if PTY_DEBUG if (print_debug) fprintf(stderr, "trying seteuid() from %d to %d...\n", euid, uid); #endif if (setuid(uid)) { warn("ERROR: IO::Tty::open_slave: couldn't seteuid to root: %d", errno); return 0; } if (chown(namebuf, euid, -1)) { warn("ERROR: IO::Tty::open_slave: couldn't fchown the pty: %d", errno); return 0; } if (seteuid(euid)) { warn("ERROR: IO::Tty::open_slave: couldn't seteuid back: %d", errno); return 0; } } } #endif if (*ttyfd >= 0) { make_safe_fd(ptyfd); make_safe_fd(ttyfd); return 1; /* we already have an open slave, so no more init is needed */ } /* * Open the slave side. */ #if PTY_DEBUG if (print_debug) fprintf(stderr, "trying to open %s...\n", namebuf); #endif *ttyfd = open(namebuf, O_RDWR | O_NOCTTY); if (*ttyfd < 0) { if (PL_dowarn) warn("IO::Tty::open_slave(nonfatal): open(%.200s): %.100s", namebuf, strerror(errno)); close(*ptyfd); return 0; /* too bad, couldn't open slave side */ } #if defined (I_PUSH) /* * Push appropriate streams modules for Solaris pty(7). * HP-UX pty(7) doesn't have ttcompat module. * We simply try to push all relevant modules but warn only on * those platforms we know these are required. */ #if PTY_DEBUG if (print_debug) fprintf(stderr, "trying to I_PUSH ptem...\n"); #endif if (ioctl(*ttyfd, I_PUSH, "ptem") < 0) #if defined (__solaris) || defined(__hpux) if (PL_dowarn) warn("IO::Tty::pty_allocate: ioctl I_PUSH ptem: %.100s", strerror(errno)) #endif ; #if PTY_DEBUG if (print_debug) fprintf(stderr, "trying to I_PUSH ldterm...\n"); #endif if (ioctl(*ttyfd, I_PUSH, "ldterm") < 0) #if defined (__solaris) || defined(__hpux) if (PL_dowarn) warn("IO::Tty::pty_allocate: ioctl I_PUSH ldterm: %.100s", strerror(errno)) #endif ; #if PTY_DEBUG if (print_debug) fprintf(stderr, "trying to I_PUSH ttcompat...\n"); #endif if (ioctl(*ttyfd, I_PUSH, "ttcompat") < 0) #if defined (__solaris) if (PL_dowarn) warn("IO::Tty::pty_allocate: ioctl I_PUSH ttcompat: %.100s", strerror(errno)) #endif ; #endif /* I_PUSH */ /* finally we make sure the filedescriptors are > 2 to avoid problems with stdin/out/err. This can happen if the user closes one of them before allocating a pty and leads to nasty side-effects, so we take a proactive stance here. Normally I would say "Those who mess with stdin/out/err shall bear the consequences to the fullest" but hey, I'm a nice guy... ;O) */ make_safe_fd(ptyfd); make_safe_fd(ttyfd); return 1; } /* * Allocates and opens a pty. Returns 0 if no pty could be allocated, or * nonzero if a pty was successfully allocated. On success, open file * descriptors for the pty and tty sides and the name of the tty side are * returned (the buffer must be able to hold at least 64 characters). * * Instead of trying just one method we go through all available * methods until we get a positive result. */ static int allocate_pty(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen) { *ptyfd = -1; *ttyfd = -1; namebuf[0] = 0; /* * first we try to get a master device */ do { /* we use do{}while(0) and break instead of goto */ #if defined(HAVE__GETPTY) /* _getpty(3) for SGI Irix */ { char *slave; mysig_t old_signal; #if PTY_DEBUG if (print_debug) fprintf(stderr, "trying _getpty()...\n"); #endif /* _getpty spawns a suid prog, so don't ignore SIGCHLD */ old_signal = mysignal(SIGCHLD, SIG_DFL); slave = _getpty(ptyfd, O_RDWR, 0622, 0); mysignal(SIGCHLD, old_signal); if (slave != NULL) { if (strlcpy(namebuf, slave, namebuflen) >= namebuflen) { warn("ERROR: pty_allocate: ttyname truncated"); return 0; } if (open_slave(ptyfd, ttyfd, namebuf, namebuflen)) break; close(*ptyfd); *ptyfd = -1; } else { if (PL_dowarn) warn("pty_allocate(nonfatal): _getpty(): %.100s", strerror(errno)); *ptyfd = -1; } } #endif #if defined(HAVE_PTSNAME) || defined(HAVE_PTSNAME_R) /* we don't need to try these if we don't have a way to get the pty names */ #if defined(HAVE_POSIX_OPENPT) #if PTY_DEBUG if (print_debug) fprintf(stderr, "trying posix_openpt()...\n"); #endif *ptyfd = posix_openpt(O_RDWR|O_NOCTTY); if (*ptyfd >= 0 && open_slave(ptyfd, ttyfd, namebuf, namebuflen)) break; /* got one */ if (PL_dowarn) warn("pty_allocate(nonfatal): posix_openpt(): %.100s", strerror(errno)); #endif /* defined(HAVE_POSIX_OPENPT) */ #if defined(HAVE_GETPT) /* glibc defines this */ #if PTY_DEBUG if (print_debug) fprintf(stderr, "trying getpt()...\n"); #endif *ptyfd = getpt(); if (*ptyfd >= 0 && open_slave(ptyfd, ttyfd, namebuf, namebuflen)) break; /* got one */ if (PL_dowarn) warn("pty_allocate(nonfatal): getpt(): %.100s", strerror(errno)); #endif /* defined(HAVE_GETPT) */ #if defined(HAVE_OPENPTY) /* openpty(3) exists in a variety of OS'es, but due to it's * broken interface (no maxlen to slavename) we'll only use it * to create the tty/pty pair and rely on ptsname to get the * name. */ { mysig_t old_signal; int ret; #if PTY_DEBUG if (print_debug) fprintf(stderr, "trying openpty()...\n"); #endif old_signal = mysignal(SIGCHLD, SIG_DFL); ret = openpty(ptyfd, ttyfd, NULL, NULL, NULL); mysignal(SIGCHLD, old_signal); if (ret >= 0 && *ptyfd >= 0) { if (open_slave(ptyfd, ttyfd, namebuf, namebuflen)) break; } *ptyfd = -1; *ttyfd = -1; if (PL_dowarn) warn("pty_allocate(nonfatal): openpty(): %.100s", strerror(errno)); } #endif /* defined(HAVE_OPENPTY) */ /* * now try various cloning devices */ #if defined(HAVE_DEV_PTMX) #if PTY_DEBUG if (print_debug) fprintf(stderr, "trying /dev/ptmx...\n"); #endif *ptyfd = open("/dev/ptmx", O_RDWR | O_NOCTTY); if (*ptyfd >= 0 && open_slave(ptyfd, ttyfd, namebuf, namebuflen)) break; if (PL_dowarn) warn("pty_allocate(nonfatal): open(/dev/ptmx): %.100s", strerror(errno)); #endif /* HAVE_DEV_PTMX */ #if defined(HAVE_DEV_PTYM_CLONE) #if PTY_DEBUG if (print_debug) fprintf(stderr, "trying /dev/ptym/clone...\n"); #endif *ptyfd = open("/dev/ptym/clone", O_RDWR | O_NOCTTY); if (*ptyfd >= 0 && open_slave(ptyfd, ttyfd, namebuf, namebuflen)) break; if (PL_dowarn) warn("pty_allocate(nonfatal): open(/dev/ptym/clone): %.100s", strerror(errno)); #endif /* HAVE_DEV_PTYM_CLONE */ #if defined(HAVE_DEV_PTC) /* AIX-style pty code. */ #if PTY_DEBUG if (print_debug) fprintf(stderr, "trying /dev/ptc...\n"); #endif *ptyfd = open("/dev/ptc", O_RDWR | O_NOCTTY); if (*ptyfd >= 0 && open_slave(ptyfd, ttyfd, namebuf, namebuflen)) break; if (PL_dowarn) warn("pty_allocate(nonfatal): open(/dev/ptc): %.100s", strerror(errno)); #endif /* HAVE_DEV_PTC */ #if defined(HAVE_DEV_PTMX_BSD) #if PTY_DEBUG if (print_debug) fprintf(stderr, "trying /dev/ptmx_bsd...\n"); #endif *ptyfd = open("/dev/ptmx_bsd", O_RDWR | O_NOCTTY); if (*ptyfd >= 0 && open_slave(ptyfd, ttyfd, namebuf, namebuflen)) break; if (PL_dowarn) warn("pty_allocate(nonfatal): open(/dev/ptmx_bsd): %.100s", strerror(errno)); #endif /* HAVE_DEV_PTMX_BSD */ #endif /* !defined(HAVE_PTSNAME) && !defined(HAVE_PTSNAME_R) */ /* * we still don't have a pty, so try some oldfashioned stuff, * looking for a pty/tty pair ourself. */ #if defined(_CRAY) { char buf[64]; int i; int highpty; #ifdef _SC_CRAY_NPTY highpty = sysconf(_SC_CRAY_NPTY); if (highpty == -1) highpty = 128; #else highpty = 128; #endif #if PTY_DEBUG if (print_debug) fprintf(stderr, "trying CRAY /dev/pty/???...\n"); #endif for (i = 0; i < highpty; i++) { sprintf(buf, "/dev/pty/%03d", i); *ptyfd = open(buf, O_RDWR | O_NOCTTY); if (*ptyfd < 0) continue; sprintf(buf, "/dev/ttyp%03d", i); if (strlcpy(namebuf, buf, namebuflen) >= namebuflen) { warn("ERROR: pty_allocate: ttyname truncated"); return 0; } break; } if (*ptyfd >= 0 && open_slave(ptyfd, ttyfd, namebuf, namebuflen)) break; } #endif #if defined(HAVE_DEV_PTYM) { /* HPUX */ char buf[64]; char tbuf[64]; int i; struct stat sb; const char *ptymajors = "abcefghijklmnopqrstuvwxyz"; const char *ptyminors = "0123456789abcdef"; int num_minors = strlen(ptyminors); int num_ptys = strlen(ptymajors) * num_minors; #if PTY_DEBUG if (print_debug) fprintf(stderr, "trying HPUX /dev/ptym/pty[a-ce-z][0-9a-f]...\n"); #endif /* try /dev/ptym/pty[a-ce-z][0-9a-f] */ for (i = 0; i < num_ptys; i++) { sprintf(buf, "/dev/ptym/pty%c%c", ptymajors[i / num_minors], ptyminors[i % num_minors]); sprintf(tbuf, "/dev/pty/tty%c%c", ptymajors[i / num_minors], ptyminors[i % num_minors]); if (strlcpy(namebuf, tbuf, namebuflen) >= namebuflen) { warn("ERROR: pty_allocate: ttyname truncated"); return 0; } if(stat(buf, &sb)) break; /* file does not exist, skip rest */ *ptyfd = open(buf, O_RDWR | O_NOCTTY); if (*ptyfd >= 0 && open_slave(ptyfd, ttyfd, namebuf, namebuflen)) break; namebuf[0] = 0; } if (*ptyfd >= 0) break; #if PTY_DEBUG if (print_debug) fprintf(stderr, "trying HPUX /dev/ptym/pty[a-ce-z][0-9][0-9]...\n"); #endif /* now try /dev/ptym/pty[a-ce-z][0-9][0-9] */ num_minors = 100; num_ptys = strlen(ptymajors) * num_minors; for (i = 0; i < num_ptys; i++) { sprintf(buf, "/dev/ptym/pty%c%02d", ptymajors[i / num_minors], i % num_minors); sprintf(tbuf, "/dev/pty/tty%c%02d", ptymajors[i / num_minors], i % num_minors); if (strlcpy(namebuf, tbuf, namebuflen) >= namebuflen) { warn("ERROR: pty_allocate: ttyname truncated"); return 0; } if(stat(buf, &sb)) break; /* file does not exist, skip rest */ *ptyfd = open(buf, O_RDWR | O_NOCTTY); if (*ptyfd >= 0 && open_slave(ptyfd, ttyfd, namebuf, namebuflen)) break; namebuf[0] = 0; } if (*ptyfd >= 0) break; } #endif /* HAVE_DEV_PTYM */ { /* BSD-style pty code. */ char buf[64]; char tbuf[64]; int i; const char *ptymajors = "pqrstuvwxyzabcdefghijklmnoABCDEFGHIJKLMNOPQRSTUVWXYZ"; const char *ptyminors = "0123456789abcdefghijklmnopqrstuv"; int num_minors = strlen(ptyminors); int num_ptys = strlen(ptymajors) * num_minors; #if PTY_DEBUG if (print_debug) fprintf(stderr, "trying BSD /dev/pty??...\n"); #endif for (i = 0; i < num_ptys; i++) { sprintf(buf, "/dev/pty%c%c", ptymajors[i / num_minors], ptyminors[i % num_minors]); sprintf(tbuf, "/dev/tty%c%c", ptymajors[i / num_minors], ptyminors[i % num_minors]); if (strlcpy(namebuf, tbuf, namebuflen) >= namebuflen) { warn("ERROR: pty_allocate: ttyname truncated"); return 0; } *ptyfd = open(buf, O_RDWR | O_NOCTTY); if (*ptyfd >= 0 && open_slave(ptyfd, ttyfd, namebuf, namebuflen)) break; /* Try SCO style naming */ sprintf(buf, "/dev/ptyp%d", i); sprintf(tbuf, "/dev/ttyp%d", i); if (strlcpy(namebuf, tbuf, namebuflen) >= namebuflen) { warn("ERROR: pty_allocate: ttyname truncated"); return 0; } *ptyfd = open(buf, O_RDWR | O_NOCTTY); if (*ptyfd >= 0 && open_slave(ptyfd, ttyfd, namebuf, namebuflen)) break; /* Try BeOS style naming */ sprintf(buf, "/dev/pt/%c%c", ptymajors[i / num_minors], ptyminors[i % num_minors]); sprintf(tbuf, "/dev/tt/%c%c", ptymajors[i / num_minors], ptyminors[i % num_minors]); if (strlcpy(namebuf, tbuf, namebuflen) >= namebuflen) { warn("ERROR: pty_allocate: ttyname truncated"); return 0; } *ptyfd = open(buf, O_RDWR | O_NOCTTY); if (*ptyfd >= 0 && open_slave(ptyfd, ttyfd, namebuf, namebuflen)) break; /* Try z/OS style naming */ sprintf(buf, "/dev/ptyp%04d", i); sprintf(tbuf, "/dev/ttyp%04d", i); if (strlcpy(namebuf, tbuf, namebuflen) >= namebuflen) { warn("ERROR: pty_allocate: ttyname truncated"); return 0; } *ptyfd = open(buf, O_RDWR | O_NOCTTY); if (*ptyfd >= 0 && open_slave(ptyfd, ttyfd, namebuf, namebuflen)) break; namebuf[0] = 0; } if (*ptyfd >= 0) break; } } while (0); if (*ptyfd < 0 || namebuf[0] == 0) return 0; /* we failed to allocate one */ return 1; /* whew, finally finished successfully */ } /* end allocate_pty */ #line 802 "Tty.c" #ifndef PERL_UNUSED_VAR # define PERL_UNUSED_VAR(var) if (0) var = var #endif #ifndef dVAR # define dVAR dNOOP #endif /* This stuff is not part of the API! You have been warned. */ #ifndef PERL_VERSION_DECIMAL # define PERL_VERSION_DECIMAL(r,v,s) (r*1000000 + v*1000 + s) #endif #ifndef PERL_DECIMAL_VERSION # define PERL_DECIMAL_VERSION \ PERL_VERSION_DECIMAL(PERL_REVISION,PERL_VERSION,PERL_SUBVERSION) #endif #ifndef PERL_VERSION_GE # define PERL_VERSION_GE(r,v,s) \ (PERL_DECIMAL_VERSION >= PERL_VERSION_DECIMAL(r,v,s)) #endif #ifndef PERL_VERSION_LE # define PERL_VERSION_LE(r,v,s) \ (PERL_DECIMAL_VERSION <= PERL_VERSION_DECIMAL(r,v,s)) #endif /* XS_INTERNAL is the explicit static-linkage variant of the default * XS macro. * * XS_EXTERNAL is the same as XS_INTERNAL except it does not include * "STATIC", ie. it exports XSUB symbols. You probably don't want that * for anything but the BOOT XSUB. * * See XSUB.h in core! */ /* TODO: This might be compatible further back than 5.10.0. */ #if PERL_VERSION_GE(5, 10, 0) && PERL_VERSION_LE(5, 15, 1) # undef XS_EXTERNAL # undef XS_INTERNAL # if defined(__CYGWIN__) && defined(USE_DYNAMIC_LOADING) # define XS_EXTERNAL(name) __declspec(dllexport) XSPROTO(name) # define XS_INTERNAL(name) STATIC XSPROTO(name) # endif # if defined(__SYMBIAN32__) # define XS_EXTERNAL(name) EXPORT_C XSPROTO(name) # define XS_INTERNAL(name) EXPORT_C STATIC XSPROTO(name) # endif # ifndef XS_EXTERNAL # if defined(HASATTRIBUTE_UNUSED) && !defined(__cplusplus) # define XS_EXTERNAL(name) void name(pTHX_ CV* cv __attribute__unused__) # define XS_INTERNAL(name) STATIC void name(pTHX_ CV* cv __attribute__unused__) # else # ifdef __cplusplus # define XS_EXTERNAL(name) extern "C" XSPROTO(name) # define XS_INTERNAL(name) static XSPROTO(name) # else # define XS_EXTERNAL(name) XSPROTO(name) # define XS_INTERNAL(name) STATIC XSPROTO(name) # endif # endif # endif #endif /* perl >= 5.10.0 && perl <= 5.15.1 */ /* The XS_EXTERNAL macro is used for functions that must not be static * like the boot XSUB of a module. If perl didn't have an XS_EXTERNAL * macro defined, the best we can do is assume XS is the same. * Dito for XS_INTERNAL. */ #ifndef XS_EXTERNAL # define XS_EXTERNAL(name) XS(name) #endif #ifndef XS_INTERNAL # define XS_INTERNAL(name) XS(name) #endif /* Now, finally, after all this mess, we want an ExtUtils::ParseXS * internal macro that we're free to redefine for varying linkage due * to the EXPORT_XSUB_SYMBOLS XS keyword. This is internal, use * XS_EXTERNAL(name) or XS_INTERNAL(name) in your code if you need to! */ #undef XS_EUPXS #if defined(PERL_EUPXS_ALWAYS_EXPORT) # define XS_EUPXS(name) XS_EXTERNAL(name) #else /* default to internal */ # define XS_EUPXS(name) XS_INTERNAL(name) #endif #ifndef PERL_ARGS_ASSERT_CROAK_XS_USAGE #define PERL_ARGS_ASSERT_CROAK_XS_USAGE assert(cv); assert(params) /* prototype to pass -Wmissing-prototypes */ STATIC void S_croak_xs_usage(const CV *const cv, const char *const params); STATIC void S_croak_xs_usage(const CV *const cv, const char *const params) { const GV *const gv = CvGV(cv); PERL_ARGS_ASSERT_CROAK_XS_USAGE; if (gv) { const char *const gvname = GvNAME(gv); const HV *const stash = GvSTASH(gv); const char *const hvname = stash ? HvNAME(stash) : NULL; if (hvname) Perl_croak_nocontext("Usage: %s::%s(%s)", hvname, gvname, params); else Perl_croak_nocontext("Usage: %s(%s)", gvname, params); } else { /* Pants. I don't think that it should be possible to get here. */ Perl_croak_nocontext("Usage: CODE(0x%" UVxf ")(%s)", PTR2UV(cv), params); } } #undef PERL_ARGS_ASSERT_CROAK_XS_USAGE #define croak_xs_usage S_croak_xs_usage #endif /* NOTE: the prototype of newXSproto() is different in versions of perls, * so we define a portable version of newXSproto() */ #ifdef newXS_flags #define newXSproto_portable(name, c_impl, file, proto) newXS_flags(name, c_impl, file, proto, 0) #else #define newXSproto_portable(name, c_impl, file, proto) (PL_Sv=(SV*)newXS(name, c_impl, file), sv_setpv(PL_Sv, proto), (CV*)PL_Sv) #endif /* !defined(newXS_flags) */ #if PERL_VERSION_LE(5, 21, 5) # define newXS_deffile(a,b) Perl_newXS(aTHX_ a,b,file) #else # define newXS_deffile(a,b) Perl_newXS_deffile(aTHX_ a,b) #endif #line 946 "Tty.c" XS_EUPXS(XS_IO__Pty_pty_allocate); /* prototype to pass -Wmissing-prototypes */ XS_EUPXS(XS_IO__Pty_pty_allocate) { dVAR; dXSARGS; if (items != 0) croak_xs_usage(cv, ""); PERL_UNUSED_VAR(ax); /* -Wall */ SP -= items; { #line 799 "Tty.xs" int ptyfd, ttyfd, ret; char name[256]; #ifdef PTY_DEBUG SV *debug; #endif #line 964 "Tty.c" #line 806 "Tty.xs" #ifdef PTY_DEBUG debug = perl_get_sv("IO::Tty::DEBUG", FALSE); if (SvTRUE(debug)) print_debug = 1; #endif ret = allocate_pty(&ptyfd, &ttyfd, name, sizeof(name)); if (ret) { name[sizeof(name)-1] = 0; EXTEND(SP,3); PUSHs(sv_2mortal(newSViv(ptyfd))); PUSHs(sv_2mortal(newSViv(ttyfd))); PUSHs(sv_2mortal(newSVpv(name, strlen(name)))); } else { /* empty list */ } #line 981 "Tty.c" PUTBACK; return; } } XS_EUPXS(XS_IO__Tty_ttyname); /* prototype to pass -Wmissing-prototypes */ XS_EUPXS(XS_IO__Tty_ttyname) { dVAR; dXSARGS; if (items != 1) croak_xs_usage(cv, "handle"); { InOutStream handle = IoIFP(sv_2io(ST(0))) ; char * RETVAL; dXSTARG; #line 829 "Tty.xs" #ifdef HAVE_TTYNAME if (handle) RETVAL = ttyname(PerlIO_fileno(handle)); else { RETVAL = Nullch; errno = EINVAL; } #else warn("IO::Tty::ttyname not implemented on this architecture"); RETVAL = Nullch; #endif #line 1011 "Tty.c" sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG; } XSRETURN(1); } XS_EUPXS(XS_IO__Tty_pack_winsize); /* prototype to pass -Wmissing-prototypes */ XS_EUPXS(XS_IO__Tty_pack_winsize) { dVAR; dXSARGS; if (items < 2 || items > 4) croak_xs_usage(cv, "row, col, xpixel = 0, ypixel = 0"); { int row = (int)SvIV(ST(0)) ; int col = (int)SvIV(ST(1)) ; int xpixel; int ypixel; SV * RETVAL; if (items < 3) xpixel = 0; else { xpixel = (int)SvIV(ST(2)) ; } if (items < 4) ypixel = 0; else { ypixel = (int)SvIV(ST(3)) ; } #line 850 "Tty.xs" struct winsize ws; #line 1048 "Tty.c" #line 852 "Tty.xs" ws.ws_row = row; ws.ws_col = col; ws.ws_xpixel = xpixel; ws.ws_ypixel = ypixel; RETVAL = newSVpvn((char *)&ws, sizeof(ws)); #line 1055 "Tty.c" RETVAL = sv_2mortal(RETVAL); ST(0) = RETVAL; } XSRETURN(1); } XS_EUPXS(XS_IO__Tty_unpack_winsize); /* prototype to pass -Wmissing-prototypes */ XS_EUPXS(XS_IO__Tty_unpack_winsize) { dVAR; dXSARGS; if (items != 1) croak_xs_usage(cv, "winsize"); PERL_UNUSED_VAR(ax); /* -Wall */ SP -= items; { SV * winsize = ST(0) ; #line 864 "Tty.xs" struct winsize ws; #line 1076 "Tty.c" #line 866 "Tty.xs" if(SvCUR(winsize) != sizeof(ws)) croak("IO::Tty::unpack_winsize(): Bad arg length - got %zd, expected %zd", SvCUR(winsize), sizeof(ws)); Copy(SvPV_nolen(winsize), &ws, sizeof(ws), char); EXTEND(SP, 4); PUSHs(sv_2mortal(newSViv(ws.ws_row))); PUSHs(sv_2mortal(newSViv(ws.ws_col))); PUSHs(sv_2mortal(newSViv(ws.ws_xpixel))); PUSHs(sv_2mortal(newSViv(ws.ws_ypixel))); #line 1087 "Tty.c" PUTBACK; return; } } #ifdef __cplusplus extern "C" #endif XS_EXTERNAL(boot_IO__Tty); /* prototype to pass -Wmissing-prototypes */ XS_EXTERNAL(boot_IO__Tty) { #if PERL_VERSION_LE(5, 21, 5) dVAR; dXSARGS; #else dVAR; dXSBOOTARGSXSAPIVERCHK; #endif #if (PERL_REVISION == 5 && PERL_VERSION < 9) char* file = __FILE__; #else const char* file = __FILE__; #endif PERL_UNUSED_VAR(file); PERL_UNUSED_VAR(cv); /* -W */ PERL_UNUSED_VAR(items); /* -W */ #if PERL_VERSION_LE(5, 21, 5) XS_VERSION_BOOTCHECK; # ifdef XS_APIVERSION_BOOTCHECK XS_APIVERSION_BOOTCHECK; # endif #endif newXS_deffile("IO::Pty::pty_allocate", XS_IO__Pty_pty_allocate); newXS_deffile("IO::Tty::ttyname", XS_IO__Tty_ttyname); newXS_deffile("IO::Tty::pack_winsize", XS_IO__Tty_pack_winsize); newXS_deffile("IO::Tty::unpack_winsize", XS_IO__Tty_unpack_winsize); /* Initialisation Section */ #line 878 "Tty.xs" { HV *stash; SV *config; stash = gv_stashpv("IO::Tty::Constant", TRUE); config = perl_get_sv("IO::Tty::CONFIG", TRUE); #include "xssubs.c" } #line 1138 "Tty.c" /* End of Initialisation Section */ #if PERL_VERSION_LE(5, 21, 5) # if PERL_VERSION_GE(5, 9, 0) if (PL_unitcheckav) call_list(PL_scopestack_ix, PL_unitcheckav); # endif XSRETURN_YES; #else Perl_xs_boot_epilog(aTHX_ ax); #endif }
Copyright ©2021 || Defacer Indonesia