summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/Errno/Errno_pm.PL3
-rw-r--r--hints/vmesa.sh333
-rw-r--r--perl.c19
-rw-r--r--perl.h22
-rw-r--r--perly.y4
-rw-r--r--pp_sys.c19
-rwxr-xr-xt/io/pipe.t72
-rwxr-xr-xt/lib/cgi-html.t2
-rwxr-xr-xt/lib/ipc_sysv.t12
-rwxr-xr-xt/op/magic.t2
-rwxr-xr-xt/op/pack.t2
-rwxr-xr-xt/op/quotemeta.t2
-rwxr-xr-xt/op/subst.t2
-rw-r--r--util.c6
-rw-r--r--vmesa/Makefile15
-rw-r--r--vmesa/vmesa.c611
-rw-r--r--vmesa/vmesaish.h15
-rw-r--r--x2p/a2p.h5
18 files changed, 1100 insertions, 46 deletions
diff --git a/ext/Errno/Errno_pm.PL b/ext/Errno/Errno_pm.PL
index 0d3ca75085..286dbc6d46 100644
--- a/ext/Errno/Errno_pm.PL
+++ b/ext/Errno/Errno_pm.PL
@@ -58,6 +58,9 @@ sub get_files {
} elsif ($^O eq 'os390') {
# OS/390 C compiler doesn't generate #file or #line directives
$file{'/usr/include/errno.h'} = 1;
+ } elsif ($^O eq 'vmesa') {
+ # OS/390 C compiler doesn't generate #file or #line directives
+ $file{'../../vmesa/errno.h'} = 1;
} else {
open(CPPI,"> errno.c") or
die "Cannot open errno.c";
diff --git a/hints/vmesa.sh b/hints/vmesa.sh
new file mode 100644
index 0000000000..29d9bf0588
--- /dev/null
+++ b/hints/vmesa.sh
@@ -0,0 +1,333 @@
+# hints/vmesa.sh
+#
+# VM/ESA hints by Neale Ferguson (neale@mailbox.tabnsw.com.au)
+
+case "$archname" in
+'') archname="$osname" ;;
+esac
+bin='/usr/local/bin'
+binexp='/usr/local/bin'
+byacc='byacc'
+c='\c'
+cc='c89'
+ccflags="-D_OE_SOCKETS -DOLD_PTHREADS_API -DYYDYNAMIC -DDEBUGGING -I.." \
+ "-I/usr/local/include -W c,hwopts\\\(string\\\),langlvl\\\(ansi\\\)"
+clocktype='clock_t'
+cryptlib="n"
+d_Gconvert='gcvt((x),(n),(b))'
+d_access='define'
+d_alarm='define'
+d_archlib='define'
+# randbits='15'
+archobjs="ebcdic.o vmesa.o"
+d_attribut='undef'
+d_bcmp='define'
+d_bcopy='define'
+d_bsd='undef'
+d_bsdgetpgrp='undef'
+d_bsdsetpgrp='undef'
+d_bzero='define'
+d_casti32='define'
+d_castneg='define'
+d_charvspr='undef'
+d_chown='define'
+d_chroot='undef'
+d_chsize='undef'
+d_closedir='define'
+d_const='define'
+d_crypt='undef'
+d_csh='undef'
+d_cuserid='define'
+d_dbl_dig='define'
+d_difftime='define'
+d_dirnamlen='undef'
+d_dlerror='define'
+d_dlopen='define'
+d_dlsymun='define'
+d_dosuid='undef'
+d_dup2='define'
+d_endgrent='undef'
+d_endpwent='undef'
+d_eofnblk='define'
+d_eunice='undef'
+d_fchmod='define'
+d_fchown='define'
+d_fcntl='define'
+d_fd_macros='define'
+d_fd_set='define'
+d_fds_bits='define'
+d_fgetpos='define'
+d_flexfnam='define'
+d_flock='undef'
+d_fork='undef'
+d_fpathconf='define'
+d_fsetpos='define'
+d_ftime='undef'
+d_getgrent='undef'
+d_gethent='define'
+d_gethname='undef'
+d_getlogin='define'
+d_getpgid='undef'
+d_getpgrp='define'
+d_getpgrp2='undef'
+d_getppid='define'
+d_getprior='undef'
+d_getpwent='undef'
+d_gettimeod='define'
+d_gnulibc='undef'
+d_htonl='define'
+d_index='define'
+d_inetaton='undef'
+d_isascii='define'
+d_killpg='define'
+d_link='define'
+d_locconv='define'
+d_lockf='define'
+d_longdbl='undef'
+d_longllong='undef'
+d_lstat='define'
+d_mblen='define'
+d_mbstowcs='define'
+d_mbtowc='define'
+d_memcmp='define'
+d_memcpy='define'
+d_memmove='define'
+d_memset='define'
+d_mkdir='define'
+d_mkfifo='define'
+d_mktime='define'
+d_msg='define'
+d_msgctl='define'
+d_msgget='define'
+d_msgrcv='define'
+d_msgsnd='define'
+d_mymalloc='undef'
+d_nice='undef'
+d_oldsock='undef'
+d_open3='define'
+d_pathconf='define'
+d_pause='define'
+d_phostname='undef'
+d_pipe='define'
+d_poll='undef'
+d_portable='define'
+d_pwage='undef'
+d_pwchange='undef'
+d_pwclass='undef'
+d_pwcomment='undef'
+d_pwexpire='undef'
+d_pwquota='undef'
+d_readdir='define'
+d_readlink='define'
+d_rename='define'
+d_rewinddir='define'
+d_rmdir='define'
+d_safebcpy='define'
+d_safemcpy='undef'
+d_sanemcmp='define'
+d_sched_yield='undef'
+d_seekdir='undef'
+d_select='define'
+d_sem='define'
+d_semctl='define'
+d_semctl_semid_ds='define'
+d_semget='define'
+d_semop='define'
+d_setegid='define'
+d_seteuid='define'
+d_setgrent='undef'
+d_setgrps='undef'
+d_setlinebuf='undef'
+d_setlocale='define'
+d_setpgid='define'
+d_setpgrp='define'
+d_setpgrp2='undef'
+d_setprior='undef'
+d_setpwent='undef'
+d_setregid='undef'
+d_setresgid='undef'
+d_setresuid='undef'
+d_setreuid='undef'
+d_setrgid='undef'
+d_setruid='undef'
+d_setsid='define'
+d_sfio='undef'
+d_shm='define'
+d_shmat='define'
+d_shmatprototype='define'
+d_shmctl='define'
+d_shmdt='define'
+d_shmget='define'
+d_sigaction='define'
+d_sigsetjmp='define'
+d_socket='define'
+d_sockpair='undef'
+d_statblks='undef'
+d_stdio_cnt_lval='undef'
+d_stdio_ptr_lval='undef'
+d_stdiobase='undef'
+d_stdstdio='undef'
+d_strchr='define'
+d_strcoll='define'
+d_strctcpy='undef'
+d_strerrm='strerror(e)'
+d_strerror='define'
+d_strtod='define'
+d_strtol='define'
+d_strtoul='define'
+d_strxfrm='define'
+d_suidsafe='undef'
+d_symlink='define'
+d_syscall='undef'
+d_sysconf='define'
+d_sysernlst="n"
+d_syserrlst='undef'
+d_system='define'
+d_tcgetpgrp='define'
+d_tcsetpgrp='define'
+d_telldir='undef'
+d_time='define'
+d_times='define'
+d_truncate='define'
+d_tzname='define'
+d_umask='define'
+d_uname='define'
+d_union_semun='undef'
+d_vfork='define'
+d_void_closedir='undef'
+d_voidsig='define'
+d_voidtty="n"
+d_volatile='define'
+d_vprintf='define'
+d_waitpid='define'
+d_wait4='undef'
+d_wcstombs='define'
+d_wctomb='define'
+d_xenix='undef'
+db_hashtype='u_int32_t'
+db_prefixtype='size_t'
+direntrytype='struct dirent'
+dlext='none'
+dlsrc='dl_vmesa.xs'
+dynamic_ext=''
+eagain='EAGAIN'
+ebcdic='define'
+exe_ext=''
+extensions='Fcntl GDBM_File IO NDBM_File Opcode POSIX Socket IPC/SysV Errno Thread attrs re Data/dumper'
+fpostype='fpos_t'
+freetype='void'
+groupstype='gid_t'
+h_fcntl='false'
+h_sysfile='true'
+hint='recommended'
+i_arpainet="define"
+i_bsdioctl="n"
+i_db='undef'
+i_dbm='define'
+i_dirent='define'
+i_dld='define'
+i_dlfcn='define'
+i_fcntl='undef'
+i_float='define'
+i_gdbm='define'
+i_grp='define'
+i_limits='define'
+i_locale='define'
+i_malloc='undef'
+i_math='define'
+i_memory='define'
+i_ndbm='define'
+i_neterrno='undef'
+i_niin='define'
+i_pwd='define'
+i_rpcsvcdbm='undef'
+i_sfio='undef'
+i_sgtty='undef'
+i_stdarg='define'
+i_stddef='define'
+i_stdlib='define'
+i_string='define'
+i_sysdir='define'
+i_sysfile='define'
+i_sysfilio='undef'
+i_sysin='undef'
+i_sysioctl='define'
+i_sysndir='undef'
+i_sysparam='undef'
+i_sysresrc='define'
+i_sysselct='undef'
+i_syssockio="n"
+i_sysstat='define'
+i_systime='define'
+i_systimek='undef'
+i_systimes='define'
+i_systypes='define'
+i_sysun='define'
+i_syswait='define'
+i_termio='undef'
+i_termios='define'
+i_time='undef'
+i_unistd='define'
+i_utime='define'
+i_values='undef'
+i_varargs='undef'
+i_varhdr='stdarg.h'
+i_vfork='undef'
+ld='c89'
+ldflags='-L/usr/local/lib -L.'
+lib_ext='.a'
+libc=''
+libperl='libperl.a'
+libpth='/usr/local/lib /lib /usr/lib'
+libs='-l//posxsock -l//vmmtlib -lgdbm -lxpg4'
+libswanted='gdbm'
+lint="n"
+locincpth='/usr/local/include /opt/local/include /usr/gnu/include /opt/gnu/include /usr/GNU/include /opt/GNU/include'
+loclibpth='/usr/local/lib /opt/local/lib /usr/gnu/lib /opt/gnu/lib /usr/GNU/lib /opt/GNU/lib'
+make_set_make='#'
+make='gnumake'
+mallocobj=''
+mallocsrc=''
+malloctype='void *'
+models='none'
+netdb_hlen_type='size_t'
+netdb_host_type='char *'
+netdb_name_type='const char *'
+netdb_net_type='in_addr_t'
+o_nonblock='O_NONBLOCK'
+obj_ext='.o'
+optimize='undef'
+prefix='/usr/local'
+prefixexp='/usr/local'
+prototype='define'
+ranlib=':'
+rd_nodata='-1'
+scriptdir='/usr/local/bin'
+scriptdirexp='/usr/local/bin'
+selecttype='fd_set *'
+shmattype='void *'
+shrpenv=''
+signal_t='void'
+sig_name_init='"ZERO","HUP","INT","ABRT","ILL","POLL","URG","STOP","FPE","KILL","BUS","SEGV","SYS","PIPE","ALRM","TERM","USR1","USR2","NUM18","CONT","CHLD","TTIN","TTOU","IO","QUIT","TSTP","TRAP","NUM27","WINCH","XCPU","XFSZ","VTALRM","PROF","NUM33","NUM34","NUM35","NUM36","NUM3","NUM38","NUM39","NUM40","NUM41","NUM42","NUM43","NUM44","NUM45","NUM46","NUM47","NUM48","NUM49","CLD"'
+sig_num='0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,20 '
+sizetype='size_t'
+so='.a'
+ssizetype='ssize_t'
+static_ext='Data/Dumper Fcntl GDBM_File IO IPC/SysV NDBM_File Opcode POSIX Socket Thread attrs re'
+stdchar='char'
+stdio_cnt='(fp)->__countIn'
+stdio_ptr='(fp)->__bufPtr'
+timeincl='sys/time.h '
+timetype='time_t'
+uidtype='uid_t'
+usedl='define'
+usemymalloc='n'
+usenm='false'
+useopcode='true'
+useperlio='undef'
+useposix='true'
+usesfio='false'
+useshrplib='false'
+usethreads='y'
+usevfork='true'
+vi='x'
diff --git a/perl.c b/perl.c
index cb0e6243a6..33a16672ae 100644
--- a/perl.c
+++ b/perl.c
@@ -1749,6 +1749,9 @@ moreswitches(char *s)
#ifdef __VOS__
printf("Stratus VOS port by Paul_Green@stratus.com, 1997-1998\n");
#endif
+#ifdef __OPEN_VM
+ printf("VM/ESA port by Neale Ferguson, 1998\n");
+#endif
#ifdef BINARY_BUILD_NOTICE
BINARY_BUILD_NOTICE;
#endif
@@ -2008,6 +2011,21 @@ sed %s -e \"/^[^#]/b\" \
%s | %_ -C %_ %s",
(PL_doextract ? "-e \"1,/^#/d\n\"" : ""),
#else
+# ifdef __OPEN_VM
+ sv_setpvf(cmd, "\
+%s %s -e '/^[^#]/b' \
+ -e '/^#[ ]*include[ ]/b' \
+ -e '/^#[ ]*define[ ]/b' \
+ -e '/^#[ ]*if[ ]/b' \
+ -e '/^#[ ]*ifdef[ ]/b' \
+ -e '/^#[ ]*ifndef[ ]/b' \
+ -e '/^#[ ]*else/b' \
+ -e '/^#[ ]*elif[ ]/b' \
+ -e '/^#[ ]*undef[ ]/b' \
+ -e '/^#[ ]*endif/b' \
+ -e 's/^[ ]*#.*//' \
+ %s | %_ %_ %s",
+# else
sv_setpvf(cmd, "\
%s %s -e '/^[^#]/b' \
-e '/^#[ ]*include[ ]/b' \
@@ -2021,6 +2039,7 @@ sed %s -e \"/^[^#]/b\" \
-e '/^#[ ]*endif/b' \
-e 's/^[ ]*#.*//' \
%s | %_ -C %_ %s",
+# endif
#ifdef LOC_SED
LOC_SED,
#else
diff --git a/perl.h b/perl.h
index 2871d8021f..bec75f7dd6 100644
--- a/perl.h
+++ b/perl.h
@@ -339,11 +339,15 @@ register struct op *op asm(stringify(OP_IN_REGISTER));
#ifdef USE_NEXT_CTYPE
-#if NX_CURRENT_COMPILER_RELEASE >= 400
-#include <objc/NXCType.h>
-#else /* NX_CURRENT_COMPILER_RELEASE < 400 */
-#include <appkit/NXCType.h>
-#endif /* NX_CURRENT_COMPILER_RELEASE >= 400 */
+#if NX_CURRENT_COMPILER_RELEASE >= 500
+# include <bsd/ctypes.h>
+#else
+# if NX_CURRENT_COMPILER_RELEASE >= 400
+# include <objc/NXCType.h>
+# else /* NX_CURRENT_COMPILER_RELEASE < 400 */
+# include <appkit/NXCType.h>
+# endif /* NX_CURRENT_COMPILER_RELEASE >= 400 */
+#endif /* NX_CURRENT_COMPILER_RELEASE >= 500 */
#else /* !USE_NEXT_CTYPE */
#include <ctype.h>
@@ -1307,7 +1311,11 @@ typedef I32 (*filter_t) _((int, SV *, int));
# if defined(__VOS__)
# include "vosish.h"
# else
-# include "unixish.h"
+# if defined(__OPEN_VM)
+# include "vmesa/vmesaish.h"
+# else
+# include "unixish.h"
+# endif
# endif
# endif
# endif
@@ -1693,7 +1701,7 @@ double atof _((const char*));
/* All of these are in stdlib.h or time.h for ANSI C */
Time_t time();
struct tm *gmtime(), *localtime();
-#ifdef OEMVS
+#if defined(OEMVS) || defined(__OPEN_VM)
char *(strchr)(), *(strrchr)();
char *(strcpy)(), *(strcat)();
#else
diff --git a/perly.y b/perly.y
index 47e632423a..2c246fc228 100644
--- a/perly.y
+++ b/perly.y
@@ -27,7 +27,7 @@ dep(void)
%start prog
%{
-#ifndef OEMVS
+#if !defined(OEMVS) && !defined(__OPEN_VM)
%}
%union {
@@ -38,7 +38,7 @@ dep(void)
}
%{
-#endif /* OEMVS */
+#endif /* !OEMVS && !__OPEN_VM*/
%}
%token <ival> '{' ')'
diff --git a/pp_sys.c b/pp_sys.c
index 7fa4de232d..4439b1c046 100644
--- a/pp_sys.c
+++ b/pp_sys.c
@@ -1467,6 +1467,13 @@ PP(pp_sysread)
PP(pp_syswrite)
{
+ djSP;
+ int items = (SP - PL_stack_base) - TOPMARK;
+ if (items == 2) {
+ EXTEND(SP, 1);
+ PUSHs(sv_2mortal(newSViv(sv_len(*SP))));
+ PUTBACK;
+ }
return pp_send(ARGS);
}
@@ -3448,7 +3455,14 @@ PP(pp_exec)
#ifdef VMS
value = (I32)vms_do_aexec(Nullsv, MARK, SP);
#else
+# ifdef __OPEN_VM
+ {
+ (void ) do_aspawn(Nullsv, MARK, SP);
+ value = 0;
+ }
+# else
value = (I32)do_aexec(Nullsv, MARK, SP);
+# endif
#endif
else {
if (PL_tainting) {
@@ -3459,7 +3473,12 @@ PP(pp_exec)
#ifdef VMS
value = (I32)vms_do_exec(SvPVx(sv_mortalcopy(*SP), PL_na));
#else
+# ifdef __OPEN_VM
+ (void) do_spawn(SvPVx(sv_mortalcopy(*SP), PL_na));
+ value = 0;
+# else
value = (I32)do_exec(SvPVx(sv_mortalcopy(*SP), PL_na));
+# endif
#endif
}
SP = ORIGMARK;
diff --git a/t/io/pipe.t b/t/io/pipe.t
index ba7a9b093b..fc3c0e5221 100755
--- a/t/io/pipe.t
+++ b/t/io/pipe.t
@@ -15,44 +15,54 @@ BEGIN {
$| = 1;
print "1..12\n";
+# External program 'tr' assumed.
open(PIPE, "|-") || (exec 'tr', 'YX', 'ko');
print PIPE "Xk 1\n";
print PIPE "oY 2\n";
close PIPE;
-if (open(PIPE, "-|")) {
- while(<PIPE>) {
- s/^not //;
- print;
+if ($^O eq 'vmesa') {
+ # Doesn't work, yet.
+ print "ok 3\n";
+ print "ok 4\n";
+ print "ok 5\n";
+ print "ok 6\n";
+} else {
+ if (open(PIPE, "-|")) {
+ while(<PIPE>) {
+ s/^not //;
+ print;
+ }
+ close PIPE; # avoid zombies which disrupt test 12
+ }
+ else {
+ # External program 'echo' assumed.
+ print STDOUT "not ok 3\n";
+ exec 'echo', 'not ok 4';
}
- close PIPE; # avoid zombies which disrupt test 12
-}
-else {
- print STDOUT "not ok 3\n";
- exec 'echo', 'not ok 4';
-}
-pipe(READER,WRITER) || die "Can't open pipe";
+ pipe(READER,WRITER) || die "Can't open pipe";
-if ($pid = fork) {
- close WRITER;
- while(<READER>) {
- s/^not //;
- y/A-Z/a-z/;
- print;
+ if ($pid = fork) {
+ close WRITER;
+ while(<READER>) {
+ s/^not //;
+ y/A-Z/a-z/;
+ print;
+ }
+ close READER; # avoid zombies which disrupt test 12
+ }
+ else {
+ die "Couldn't fork" unless defined $pid;
+ close READER;
+ print WRITER "not ok 5\n";
+ open(STDOUT,">&WRITER") || die "Can't dup WRITER to STDOUT";
+ close WRITER;
+ # External program 'echo' assumed.
+ exec 'echo', 'not ok 6';
}
- close READER; # avoid zombies which disrupt test 12
-}
-else {
- die "Couldn't fork" unless defined $pid;
- close READER;
- print WRITER "not ok 5\n";
- open(STDOUT,">&WRITER") || die "Can't dup WRITER to STDOUT";
- close WRITER;
- exec 'echo', 'not ok 6';
}
-
pipe(READER,WRITER) || die "Can't open pipe";
close READER;
@@ -99,6 +109,14 @@ else {
}
}
+if ($^O eq 'vmesa') {
+ # These don't work, yet.
+ print "ok 10\n";
+ print "ok 11\n";
+ print "ok 12\n";
+ exit;
+}
+
# check that errno gets forced to 0 if the piped program exited non-zero
open NIL, '|exit 23;' or die "fork failed: $!";
$! = 1;
diff --git a/t/lib/cgi-html.t b/t/lib/cgi-html.t
index 16aa824c51..9d11946ed0 100755
--- a/t/lib/cgi-html.t
+++ b/t/lib/cgi-html.t
@@ -10,7 +10,7 @@ BEGIN {
BEGIN {$| = 1; print "1..17\n"; }
BEGIN {$eol = $^O eq 'VMS' ? "\n" : "\cM\cJ";
- $eol = "\r\n" if $^O eq 'os390'; }
+ $eol = "\r\n" if $^O eq 'os390' or $^O eq 'vmesa'; }
END {print "not ok 1\n" unless $loaded;}
use CGI (':standard','-no_debug');
$loaded = 1;
diff --git a/t/lib/ipc_sysv.t b/t/lib/ipc_sysv.t
index 30ea48d999..fbaf19a1e0 100755
--- a/t/lib/ipc_sysv.t
+++ b/t/lib/ipc_sysv.t
@@ -49,11 +49,19 @@ EOM
exit(1);
};
+my $perm;
+
+$perm = S_IRWXU | S_IRWXG | S_IRWXO | S_IWGRP | S_IROTH | S_IWOTH
+ if $^O eq 'vmesa';
+
+$perm = S_IRWXU | S_IRWXG | S_IRWXO unless defined $perm;
+
if ($Config{'d_msgget'} eq 'define' &&
$Config{'d_msgctl'} eq 'define' &&
$Config{'d_msgsnd'} eq 'define' &&
$Config{'d_msgrcv'} eq 'define') {
- $msg = msgget(IPC_PRIVATE, S_IRWXU | S_IRWXG | S_IRWXO);
+
+ $msg = msgget(IPC_PRIVATE, $perm);
# Very first time called after machine is booted value may be 0
die "msgget failed: $!\n" unless defined($msg) && $msg >= 0;
@@ -92,7 +100,7 @@ if($Config{'d_semget'} eq 'define' &&
use IPC::SysV qw(IPC_CREAT GETALL SETALL);
- $sem = semget(IPC_PRIVATE, 10, S_IRWXU | S_IRWXG | S_IRWXO | IPC_CREAT);
+ $sem = semget(IPC_PRIVATE, 10, $perm | IPC_CREAT);
# Very first time called after machine is booted value may be 0
die "semget: $!\n" unless defined($sem) && $sem >= 0;
diff --git a/t/op/magic.t b/t/op/magic.t
index 9d05b55d1f..686424f487 100755
--- a/t/op/magic.t
+++ b/t/op/magic.t
@@ -135,7 +135,7 @@ __END__
:endofperl
EOT
}
- if ($^O eq 'os390') { # no shebang
+ if ($^O eq 'os390' or $^O eq 'vmesa') { # no shebang
$headmaybe = <<EOH ;
eval 'exec ./perl -S \$0 \${1+"\$\@"}'
if 0;
diff --git a/t/op/pack.t b/t/op/pack.t
index 725a0cb87f..1953968d3e 100755
--- a/t/op/pack.t
+++ b/t/op/pack.t
@@ -31,7 +31,7 @@ print +($x = unpack("%32B69", "\001\002\004\010\020\040\100\200\017")) == 9
? "ok 6\n" : "not ok 6 $x\n";
my $sum = 129; # ASCII
-$sum = 103 if ($^O eq 'os390'); # An EBCDIC variant.
+$sum = 103 if ($^O eq 'os390' or $^O eq 'vmesa'); # EBCDIC.
print +($x = unpack("%32B*", "Now is the time for all good blurfl")) == $sum
? "ok 7\n" : "not ok 7 $x\n";
diff --git a/t/op/quotemeta.t b/t/op/quotemeta.t
index 913e07cdd6..0217a67a93 100755
--- a/t/op/quotemeta.t
+++ b/t/op/quotemeta.t
@@ -2,7 +2,7 @@
print "1..15\n";
-if ($^O eq 'os390') { # An EBCDIC variant.
+if ($^O eq 'os390' or $^O eq 'vmesa') { # EBCDIC.
$_=join "", map chr($_), 129..233;
# 105 characters - 52 letters = 53 backslashes
diff --git a/t/op/subst.t b/t/op/subst.t
index d224165b8f..3b3bc8d800 100755
--- a/t/op/subst.t
+++ b/t/op/subst.t
@@ -183,7 +183,7 @@ tr/a-z/A-Z/;
print $_ eq 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' ? "ok 52\n" : "not ok 52\n";
# same as tr/A-Z/a-z/;
-if ($^O eq 'os390') { # An EBCDIC variant.
+if ($^O eq 'os390' or $^O eq 'vmesa') { # EBCDIC.
no utf8;
y[\301-\351][\201-\251];
} else { # Ye Olde ASCII. Or something like it.
diff --git a/util.c b/util.c
index 0a70c6ba5d..e705402bba 100644
--- a/util.c
+++ b/util.c
@@ -1878,7 +1878,7 @@ VTOH(vtohl,long)
#endif
/* VMS' my_popen() is in VMS.c, same with OS/2. */
-#if (!defined(DOSISH) || defined(HAS_FORK) || defined(AMIGAOS)) && !defined(VMS)
+#if (!defined(DOSISH) || defined(HAS_FORK) || defined(AMIGAOS)) && !defined(VMS) && !defined(__OPEN_VM)
PerlIO *
my_popen(char *cmd, char *mode)
{
@@ -2130,7 +2130,7 @@ rsignal_restore(int signo, Sigsave_t *save)
#endif /* !HAS_SIGACTION */
/* VMS' my_pclose() is in VMS.c; same with OS/2 */
-#if (!defined(DOSISH) || defined(HAS_FORK) || defined(AMIGAOS)) && !defined(VMS)
+#if (!defined(DOSISH) || defined(HAS_FORK) || defined(AMIGAOS)) && !defined(VMS) && !defined(__OPEN_VM)
I32
my_pclose(PerlIO *ptr)
{
@@ -2451,7 +2451,7 @@ scan_hex(char *start, I32 len, I32 *retlen)
while (len-- && *s) {
tmp = strchr((char *) PL_hexdigit, *s++);
if (!tmp) {
- if (*s == '_')
+ if (*(s-1) == '_')
continue;
else {
dTHR;
diff --git a/vmesa/Makefile b/vmesa/Makefile
new file mode 100644
index 0000000000..28c1265849
--- /dev/null
+++ b/vmesa/Makefile
@@ -0,0 +1,15 @@
+CCCMD=`sh $(shellflags) ../cflags $@`
+
+all : vm perl
+
+depend :
+;cd ..; $(MAKE) depend
+
+vm : vmesa.o
+;cp vmesa.o ../
+
+perl :
+;cd ..; $(MAKE)
+
+vmesa.o : vmesa.c
+;$(CCCMD) vmesa.c
diff --git a/vmesa/vmesa.c b/vmesa/vmesa.c
new file mode 100644
index 0000000000..0e9baf302f
--- /dev/null
+++ b/vmesa/vmesa.c
@@ -0,0 +1,611 @@
+/************************************************************/
+/* */
+/* Module ID - vmesa.c */
+/* */
+/* Function - Provide operating system dependent process- */
+/* ing for perl under VM/ESA. */
+/* */
+/* Parameters - See individual entry points. */
+/* */
+/* Called By - N/A - see individual entry points. */
+/* */
+/* Calling To - N/A - see individual entry points. */
+/* */
+/* Notes - (1) ....................................... */
+/* */
+/* (2) ....................................... */
+/* */
+/* Name - Neale Ferguson. */
+/* */
+/* Date - August, 1998. */
+/* */
+/* */
+/* Associated - (1) Refer To ........................... */
+/* Documentation */
+/* (2) Refer To ........................... */
+/* */
+/************************************************************/
+/************************************************************/
+/* */
+/* MODULE MAINTENANCE HISTORY */
+/* -------------------------- */
+/* */
+static char REQ_REL_WHO [13] =
+/*-------------- -------------------------------------*/
+ "9999_99 NAF "; /* Original module */
+/* */
+/*============ End of Module Maintenance History ===========*/
+
+/************************************************************/
+/* */
+/* DEFINES */
+/* ------- */
+/* */
+/************************************************************/
+
+#define FAIL 65280
+
+/*=============== END OF DEFINES ===========================*/
+
+/************************************************************/
+/* */
+/* INCLUDE STATEMENTS */
+/* ------------------ */
+/* */
+/************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <spawn.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <dll.h>
+#include "EXTERN.h"
+#include "perl.h"
+#pragma map(truncate, "@@TRUNC")
+
+/*================== End of Include Statements =============*/
+
+/************************************************************/
+/* */
+/* Global Variables */
+/* ---------------- */
+/* */
+/************************************************************/
+
+static int Perl_stdin_fd = STDIN_FILENO,
+ Perl_stdout_fd = STDOUT_FILENO;
+
+static long dl_retcode = 0;
+
+/*================== End of Global Variables ===============*/
+
+/************************************************************/
+/* */
+/* FUNCTION PROTOTYPES */
+/* ------------------- */
+/* */
+/************************************************************/
+
+int do_aspawn(SV *, SV **, SV **);
+int do_spawn(char *, int);
+static int spawnit(char *);
+static pid_t spawn_cmd(char *, int, int);
+struct perl_thread * getTHR(void);
+
+/*================== End of Prototypes =====================*/
+
+/************************************************************/
+/* */
+/* D O _ A S P A W N */
+/* ----------------- */
+/* */
+/************************************************************/
+
+int
+do_aspawn(SV* really, SV **mark, SV **sp)
+{
+ char **a,
+ *tmps;
+ struct inheritance inherit;
+ pid_t pid;
+ int status,
+ fd,
+ nFd,
+ fdMap[3];
+ SV *sv,
+ **p_sv;
+
+ status = FAIL;
+ if (sp > mark)
+ {
+ dTHR;
+ New(401,PL_Argv, sp - mark + 1, char*);
+ a = PL_Argv;
+ while (++mark <= sp)
+ {
+ if (*mark)
+ *a++ = SvPVx(*mark, na);
+ else
+ *a++ = "";
+ }
+ inherit.flags = SPAWN_SETGROUP;
+ inherit.pgroup = SPAWN_NEWPGROUP;
+ fdMap[STDIN_FILENO] = Perl_stdin_fd;
+ fdMap[STDOUT_FILENO] = Perl_stdout_fd;
+ fdMap[STDERR_FILENO] = STDERR_FILENO;
+ nFd = 3;
+ *a = Nullch;
+ /*-----------------------------------------------------*/
+ /* Will execvp() use PATH? */
+ /*-----------------------------------------------------*/
+ if (*PL_Argv[0] != '/')
+ TAINT_ENV();
+ if (really && *(tmps = SvPV(really, na)))
+ pid = spawnp(tmps, nFd, fdMap, &inherit,
+ (const char **) PL_Argv,
+ (const char **) environ);
+ else
+ pid = spawnp(PL_Argv[0], nFd, fdMap, &inherit,
+ (const char **) PL_Argv,
+ (const char **) environ);
+ if (pid < 0)
+ {
+ status = FAIL;
+ if (ckWARN(WARN_EXEC))
+ warner(WARN_EXEC,"Can't exec \"%s\": %s",
+ PL_Argv[0],
+ Strerror(errno));
+ }
+ else
+ {
+ /*------------------------------------------------*/
+ /* If the file descriptors have been remapped then*/
+ /* we've been called following a my_popen request */
+ /* therefore we don't want to wait for spawnned */
+ /* program to complete. We need to set the fdpid */
+ /* value to the value of the spawnned process' pid*/
+ /*------------------------------------------------*/
+ fd = 0;
+ if (Perl_stdin_fd != STDIN_FILENO)
+ fd = Perl_stdin_fd;
+ else
+ if (Perl_stdout_fd != STDOUT_FILENO)
+ fd = Perl_stdout_fd;
+ if (fd != 0)
+ {
+ /*---------------------------------------------*/
+ /* Get the fd of the other end of the pipe, */
+ /* use this to reference the fdpid which will */
+ /* be used by my_pclose */
+ /*---------------------------------------------*/
+ close(fd);
+ p_sv = av_fetch(PL_fdpid,fd,TRUE);
+ fd = (int) SvIVX(*p_sv);
+ SvREFCNT_dec(*p_sv);
+ *p_sv = &PL_sv_undef;
+ sv = *av_fetch(PL_fdpid,fd,TRUE);
+ (void) SvUPGRADE(sv, SVt_IV);
+ SvIVX(sv) = pid;
+ status = 0;
+ }
+ else
+ wait4pid(pid, &status, 0);
+ }
+ do_execfree();
+ }
+ return (status);
+}
+
+/*===================== End of do_aspawn ===================*/
+
+/************************************************************/
+/* */
+/* D O _ S P A W N */
+/* --------------- */
+/* */
+/************************************************************/
+
+int
+do_spawn(char *cmd, int execf)
+{
+ char **a,
+ *s,
+ flags[10];
+ int status,
+ nFd,
+ fdMap[3];
+ struct inheritance inherit;
+ pid_t pid;
+
+ while (*cmd && isSPACE(*cmd))
+ cmd++;
+
+ /*------------------------------------------------------*/
+ /* See if there are shell metacharacters in it */
+ /*------------------------------------------------------*/
+
+ if (*cmd == '.' && isSPACE(cmd[1]))
+ return (spawnit(cmd));
+ else
+ {
+ if (strnEQ(cmd,"exec",4) && isSPACE(cmd[4]))
+ return (spawnit(cmd));
+ else
+ {
+ /*------------------------------------------------*/
+ /* Catch VAR=val gizmo */
+ /*------------------------------------------------*/
+ for (s = cmd; *s && isALPHA(*s); s++);
+ if (*s != '=')
+ {
+ for (s = cmd; *s; s++)
+ {
+ if (*s != ' ' &&
+ !isALPHA(*s) &&
+ strchr("$&*(){}[]'\";\\|?<>~`\n",*s))
+ {
+ if (*s == '\n' && !s[1])
+ {
+ *s = '\0';
+ break;
+ }
+ return(spawnit(cmd));
+ }
+ }
+ }
+ }
+ }
+
+ New(402,PL_Argv, (s - cmd) / 2 + 2, char*);
+ PL_Cmd = savepvn(cmd, s-cmd);
+ a = PL_Argv;
+ for (s = PL_Cmd; *s;)
+ {
+ while (*s && isSPACE(*s)) s++;
+ if (*s)
+ *(a++) = s;
+ while (*s && !isSPACE(*s)) s++;
+ if (*s)
+ *s++ = '\0';
+ }
+ *a = Nullch;
+ fdMap[STDIN_FILENO] = Perl_stdin_fd;
+ fdMap[STDOUT_FILENO] = Perl_stdout_fd;
+ fdMap[STDERR_FILENO] = STDERR_FILENO;
+ nFd = 3;
+ inherit.flags = 0;
+ if (PL_Argv[0])
+ {
+ pid = spawnp(PL_Argv[0], nFd, fdMap, &inherit,
+ (const char **) PL_Argv,
+ (const char **) environ);
+ if (pid < 0)
+ {
+ dTHR;
+ status = FAIL;
+ if (ckWARN(WARN_EXEC))
+ warner(WARN_EXEC,"Can't exec \"%s\": %s",
+ PL_Argv[0],
+ Strerror(errno));
+ }
+ else
+ wait4pid(pid, &status, 0);
+ }
+ do_execfree();
+ return (status);
+}
+
+/*===================== End of do_spawn ====================*/
+
+/************************************************************/
+/* */
+/* Name - spawnit. */
+/* */
+/* Function - Spawn command and return status. */
+/* */
+/* On Entry - cmd - command to be spawned. */
+/* */
+/* On Exit - status returned. */
+/* */
+/************************************************************/
+
+int
+spawnit(char *cmd)
+{
+ pid_t pid;
+ int status;
+
+ pid = spawn_cmd(cmd, STDIN_FILENO, STDOUT_FILENO);
+ if (pid < 0)
+ status = FAIL;
+ else
+ wait4pid(pid, &status, 0);
+
+ return (status);
+}
+
+/*===================== End of spawnit =====================*/
+
+/************************************************************/
+/* */
+/* Name - spawn_cmd. */
+/* */
+/* Function - Spawn command and return pid. */
+/* */
+/* On Entry - cmd - command to be spawned. */
+/* */
+/* On Exit - pid returned. */
+/* */
+/************************************************************/
+
+pid_t
+spawn_cmd(char *cmd, int inFd, int outFd)
+{
+ struct inheritance inherit;
+ pid_t pid;
+ const char *argV[4] = {"/bin/sh","-c",NULL,NULL};
+ int nFd,
+ fdMap[3];
+
+ argV[2] = cmd;
+ fdMap[STDIN_FILENO] = inFd;
+ fdMap[STDOUT_FILENO] = outFd;
+ fdMap[STDERR_FILENO] = STDERR_FILENO;
+ nFd = 3;
+ inherit.flags = SPAWN_SETGROUP;
+ inherit.pgroup = SPAWN_NEWPGROUP;
+ pid = spawn(argV[0], nFd, fdMap, &inherit,
+ argV, (const char **) environ);
+ return (pid);
+}
+
+/*===================== End of spawnit =====================*/
+
+/************************************************************/
+/* */
+/* Name - my_popen. */
+/* */
+/* Function - Use popen to execute a command return a */
+/* file descriptor. */
+/* */
+/* On Entry - cmd - command to be executed. */
+/* */
+/* On Exit - FILE * returned. */
+/* */
+/************************************************************/
+
+#include <ctest.h>
+PerlIO *
+my_popen(char *cmd, char *mode)
+{
+ FILE *fd;
+ int pFd[2],
+ this,
+ that,
+ pid;
+ SV *sv;
+
+ if (PerlProc_pipe(pFd) >= 0)
+ {
+ this = (*mode == 'w');
+ that = !this;
+ /*-------------------------------------------------*/
+ /* If this is a read mode pipe */
+ /* - map the write end of the pipe to STDOUT */
+ /* - return the *FILE for the read end of the pipe */
+ /*-------------------------------------------------*/
+ if (!this)
+ Perl_stdout_fd = pFd[that];
+ /*-------------------------------------------------*/
+ /* Else */
+ /* - map the read end of the pipe to STDIN */
+ /* - return the *FILE for the write end of the pipe*/
+ /*-------------------------------------------------*/
+ else
+ Perl_stdin_fd = pFd[that];
+ if (strNE(cmd,"-"))
+ {
+ pid = spawn_cmd(cmd, Perl_stdin_fd, Perl_stdout_fd);
+ if (pid >= 0)
+ {
+ sv = *av_fetch(PL_fdpid,pFd[this],TRUE);
+ (void) SvUPGRADE(sv, SVt_IV);
+ SvIVX(sv) = pid;
+ fd = PerlIO_fdopen(pFd[this], mode);
+ close(pFd[that]);
+ }
+ else
+ fd = Nullfp;
+ }
+ else
+ {
+ sv = *av_fetch(PL_fdpid,pFd[that],TRUE);
+ (void) SvUPGRADE(sv, SVt_IV);
+ SvIVX(sv) = pFd[this];
+ fd = PerlIO_fdopen(pFd[this], mode);
+ }
+ }
+ else
+ fd = Nullfp;
+ return (fd);
+}
+
+/*===================== End of my_popen ====================*/
+
+/************************************************************/
+/* */
+/* Name - my_pclose. */
+/* */
+/* Function - Use pclose to terminate a piped command */
+/* file stream. */
+/* */
+/* On Entry - fd - FILE pointer. */
+/* */
+/* On Exit - Status returned. */
+/* */
+/************************************************************/
+
+long
+my_pclose(FILE *fp)
+{
+ int pid,
+ saveErrno,
+ status;
+ long rc,
+ wRc;
+ SV **sv;
+ FILE *other;
+
+ sv = av_fetch(PL_fdpid,PerlIO_fileno(fp),TRUE);
+ pid = (int) SvIVX(*sv);
+ SvREFCNT_dec(*sv);
+ *sv = &PL_sv_undef;
+ rc = PerlIO_close(fp);
+ saveErrno = errno;
+ do
+ {
+ wRc = waitpid(pid, &status, 0);
+ } while ((wRc == -1) && (errno == EINTR));
+ Perl_stdin_fd = STDIN_FILENO;
+ Perl_stdout_fd = STDOUT_FILENO;
+ errno = saveErrno;
+ if (rc != 0)
+ SETERRNO(errno, garbage);
+ return (rc);
+
+}
+
+/*===================== End of my_pclose ===================*/
+
+/************************************************************/
+/* */
+/* Name - getTHR. */
+/* */
+/* Function - Use pclose to terminate a piped command */
+/* file stream. */
+/* */
+/* On Exit - Thread specific data returned. */
+/* */
+/************************************************************/
+
+struct perl_thread *
+getTHR()
+{
+ int status;
+ struct perl_thread *pThread;
+
+ status = pthread_getspecific(PL_thr_key, (void **) &pThread);
+ if (status != 0)
+ pThread = NULL;
+ return (pThread);
+}
+
+/*===================== End of getTHR ======================*/
+
+/************************************************************/
+/* */
+/* Name - dlopen. */
+/* */
+/* Function - Load a DLL. */
+/* */
+/* On Exit - */
+/* */
+/************************************************************/
+
+void *
+dlopen(const char *path)
+{
+ dllhandle *handle;
+
+fprintf(stderr,"Loading %s\n",path);
+ handle = dllload(path);
+ dl_retcode = errno;
+fprintf(stderr,"Handle %08X %s\n",handle,strerror(errno));
+ return ((void *) handle);
+}
+
+/*===================== End of dlopen ======================*/
+
+/************************************************************/
+/* */
+/* Name - dlsym. */
+/* */
+/* Function - Locate a DLL symbol. */
+/* */
+/* On Exit - */
+/* */
+/************************************************************/
+
+void *
+dlsym(void *handle, const char *symbol)
+{
+ void *symLoc;
+
+fprintf(stderr,"Finding %s\n",symbol);
+ symLoc = dllqueryvar((dllhandle *) handle, (char *) symbol);
+ if (symLoc == NULL)
+ symLoc = (void *) dllqueryfn((dllhandle *) handle,
+ (char *) symbol);
+ dl_retcode = errno;
+ return(symLoc);
+}
+
+/*===================== End of dlsym =======================*/
+
+/************************************************************/
+/* */
+/* Name - dlerror. */
+/* */
+/* Function - Return the last errno pertaining to a DLL */
+/* operation. */
+/* */
+/* On Exit - */
+/* */
+/************************************************************/
+
+void *
+dlerror(void)
+{
+ char * dlEmsg;
+
+ dlEmsg = strerror(dl_retcode);
+ dl_retcode = 0;
+ return(dlEmsg);
+}
+
+/*===================== End of dlerror =====================*/
+
+/************************************************************/
+/* */
+/* Name - TRUNCATE. */
+/* */
+/* Function - Truncate a file identified by 'path' to */
+/* a given length. */
+/* */
+/* On Entry - path - Path of file to be truncated. */
+/* length - length of truncated file. */
+/* */
+/* On Exit - retC - return code. */
+/* */
+/************************************************************/
+
+int
+truncate(const unsigned char *path, off_t length)
+{
+ int fd,
+ retC;
+
+ fd = open((const char *) path, O_RDWR);
+ if (fd > 0)
+ {
+ retC = ftruncate(fd, length);
+ close(fd);
+ }
+ else
+ retC = fd;
+ return(retC);
+}
+
+/*===================== End of trunc =======================*/
diff --git a/vmesa/vmesaish.h b/vmesa/vmesaish.h
new file mode 100644
index 0000000000..f4f87a93cc
--- /dev/null
+++ b/vmesa/vmesaish.h
@@ -0,0 +1,15 @@
+#ifndef _VMESA_INCLUDED
+# define _VMESA_INCLUDED 1
+# include <string.h>
+# include <ctype.h>
+# include <vmsock.h>
+ void * dlopen(const char *);
+ void * dlsym(void *, const char *);
+ void * dlerror(void);
+# ifdef YIELD
+# undef YIELD
+# endif
+# define YIELD pthread_yield(NULL)
+# define pthread_mutexattr_default NULL
+# define pthread_condattr_default NULL
+#endif
diff --git a/x2p/a2p.h b/x2p/a2p.h
index 80530469ed..392e9e66a2 100644
--- a/x2p/a2p.h
+++ b/x2p/a2p.h
@@ -138,8 +138,13 @@
/* All of these are in stdlib.h or time.h for ANSI C */
Time_t time();
struct tm *gmtime(), *localtime();
+#if defined(OEMVS) || defined(__OPEN_VM)
+char *(strchr)(), *(strrchr)();
+char *(strcpy)(), *(strcat)();
+#else
char *strchr(), *strrchr();
char *strcpy(), *strcat();
+#endif
#endif /* ! STANDARD_C */
#ifdef VMS