# define RTL_USES_UTC 1
#endif
+#if !defined(__VAX) && __CRTL_VER >= 80200000
+#ifdef lstat
+#undef lstat
+#endif
+#else
+#ifdef lstat
+#undef lstat
+#endif
+#define lstat(_x, _y) stat(_x, _y)
+#endif
+
/* Routine to create a decterm for use with the Perl debugger */
/* No headers, this information was found in the Programming Concepts Manual */
#if defined(PERL_IMPLICIT_CONTEXT)
if (aTHX == NULL) {
fprintf(stderr,
- "%%PERL-W-VMS_INIT Can't read CRTL environ\n");
+ "Can't read CRTL environ\n");
} else
#endif
Perl_warn(aTHX_ "Can't read CRTL environ\n");
#if defined(PERL_IMPLICIT_CONTEXT)
if (aTHX == NULL) {
fprintf(stderr,
- "%Perl-VMS-Init, Value of CLI symbol \"%s\" too long",lnm);
+ "Value of CLI symbol \"%s\" too long",lnm);
} else
#endif
if (ckWARN(WARN_MISC)) {
/* vmssetuserlnm
* sets a user-mode logical in the process logical name table
* used for redirection of sys$error
+ *
+ * Fix-me: The pTHX is not needed for this routine, however doio.c
+ * is calling it with one instead of using a macro.
+ * A macro needs to be added to vmsish.h and doio.c updated to use it.
+ *
*/
void
Perl_vmssetuserlnm(pTHX_ const char *name, const char *eqv)
/* lstat returns a VMS fileified specification of the name */
/* that is looked up, and also lets verifies that this is a directory */
- retval = Perl_flex_lstat(NULL, name, &st);
+ retval = flex_lstat(name, &st);
if (retval != 0) {
char * ret_spec;
/* Convert the filename to VMS format and see if it is a directory */
/* flex_lstat returns a vmsified file specification */
- rmsts = Perl_flex_lstat(NULL, name, &st);
+ rmsts = flex_lstat(name, &st);
if (rmsts != 0) {
/* Due to a historical feature, flex_stat/lstat can not see some */
* null file name/type. However, it's commonplace under Unix,
* so we'll allow it for a gain in portability.
*
- * - Preview- '/' will be valid soon on VMS
+ * '/' is valid when SYS$POSIX_ROOT or POSIX compliant pathnames are active.
*/
if ((dirlen > 1) && (dir1[dirlen-1] == '/')) {
- char *newdir = savepvn(dir1,dirlen-1);
- int ret = chdir(newdir);
- Safefree(newdir);
- return ret;
+ char *newdir;
+ int ret;
+ newdir = PerlMem_malloc(dirlen);
+ if (newdir ==NULL)
+ _ckvmssts_noperl(SS$_INSFMEM);
+ strncpy(newdir, dir1, dirlen-1);
+ newdir[dirlen-1] = '\0';
+ ret = chdir(newdir);
+ PerlMem_free(newdir);
+ return ret;
}
else return chdir(dir1);
} /* end of my_chdir */
int
Perl_my_chmod(pTHX_ const char *file_spec, mode_t mode)
{
+ Stat_t st;
+ int ret = -1;
+ char * changefile;
STRLEN speclen = strlen(file_spec);
/* zero length string sometimes gives ACCVIO */
* Tests are showing that chmod() on VMS 8.3 is only accepting directories
* in VMS file.dir notation.
*/
- if ((speclen > 1) && (file_spec[speclen-1] == '/')) {
- char *vms_src, *vms_dir, *rslt;
- int ret = -1;
- errno = EIO;
-
- /* First convert this to a VMS format specification */
- vms_src = PerlMem_malloc(VMS_MAXRSS);
- if (vms_src == NULL)
- _ckvmssts_noperl(SS$_INSFMEM);
+ changefile = (char *) file_spec; /* cast ok */
+ ret = flex_lstat(file_spec, &st);
+ if (ret != 0) {
- rslt = do_tovmsspec(file_spec, vms_src, 0, NULL);
- if (rslt == NULL) {
- /* If we fail, then not a file specification */
- PerlMem_free(vms_src);
- errno = EIO;
- return -1;
- }
-
- /* Now make it a directory spec so chmod is happy */
- vms_dir = PerlMem_malloc(VMS_MAXRSS + 1);
- if (vms_dir == NULL)
- _ckvmssts_noperl(SS$_INSFMEM);
- rslt = do_fileify_dirspec(vms_src, vms_dir, 0, NULL);
- PerlMem_free(vms_src);
+ /* Due to a historical feature, flex_stat/lstat can not see some */
+ /* Unix format file names that the rest of the CRTL can see when */
+ /* ODS-2 file specifications are in use. */
+ /* Fixing that feature will cause some perl tests to fail */
+ /* [.lib.ExtUtils.t]Manifest.t is one of them */
+ st.st_mode = 0;
- /* Now do it */
- if (rslt != NULL) {
- ret = chmod(vms_dir, mode);
- } else {
- errno = EIO;
- }
- PerlMem_free(vms_dir);
- return ret;
+ } else {
+ /* It may be possible to get here with nothing in st_devname */
+ /* chmod still may work though */
+ if (st.st_devnam[0] != 0) {
+ changefile = st.st_devnam;
+ }
}
- else return chmod(file_spec, mode);
+ ret = chmod(changefile, mode);
+ return ret;
} /* end of my_chmod */
/*}}}*/
/* default piping mailbox size */
-#define PERL_BUFSIZ 512
+#ifdef __VAX
+# define PERL_BUFSIZ 512
+#else
+# define PERL_BUFSIZ 8192
+#endif
static void
#if defined(USE_ITHREADS)
&& my_perl
#endif
- && PL_perlio_fd_refcnt)
+#ifdef USE_PERLIO
+ && PL_perlio_fd_refcnt
+#endif
+ )
PerlIO_flush(info->fp);
else
fflush((FILE *)info->fp);
if (*in_mode == 'r') {
PerlIO * xterm_fd;
+#if defined(PERL_IMPLICIT_CONTEXT)
+ /* Can not fork an xterm with a NULL context */
+ /* This probably could never happen */
+ xterm_fd = NULL;
+ if (aTHX != NULL)
+#endif
xterm_fd = create_forked_xterm(aTHX_ cmd, in_mode);
if (xterm_fd != NULL)
return xterm_fd;
#if defined(USE_ITHREADS)
&& my_perl
#endif
- && PL_perlio_fd_refcnt)
+#ifdef USE_PERLIO
+ && PL_perlio_fd_refcnt
+#endif
+ )
PerlIO_flush(info->fp);
else
fflush((FILE *)info->fp);
#if defined(USE_ITHREADS)
&& my_perl
#endif
- && PL_perlio_fd_refcnt)
+#ifdef USE_PERLIO
+ && PL_perlio_fd_refcnt
+#endif
+ )
PerlIO_close(info->fp);
else
fclose((FILE *)info->fp);
rms_set_fna(myfab, mynam, (char *)vmsname, strlen(vmsname)); /* cast ok */
rms_bind_fab_nam(myfab, mynam);
- /* Are we removing all versions? */
- if (vms_unlink_all_versions == 1) {
- const char * defspec = ";*";
- rms_set_dna(myfab, mynam, (char *)defspec, strlen(defspec)); /* cast ok */
- }
-
#ifdef NAML$M_OPEN_SPECIAL
rms_set_nam_nop(mynam, NAML$M_OPEN_SPECIAL);
#endif
Stat_t dst_st;
/* Validate the source file */
- src_sts = Perl_flex_lstat(NULL, src, &src_st);
+ src_sts = flex_lstat(src, &src_st);
if (src_sts != 0) {
/* No source file or other problem */
return -1;
}
- dst_sts = Perl_flex_lstat(NULL, dst, &dst_st);
+ dst_sts = flex_lstat(dst, &dst_st);
if (dst_sts == 0) {
if (dst_st.st_dev != src_st.st_dev) {
if (!S_ISDIR(dst_st.st_mode) || S_ISDIR(src_st.st_mode)) {
int d_sts;
- d_sts = mp_do_kill_file(NULL, dst_st.st_devnam,
+ d_sts = mp_do_kill_file(aTHX_ dst_st.st_devnam,
S_ISDIR(dst_st.st_mode));
/* Need to delete all versions ? */
int i = 0;
while (lstat(dst_st.st_devnam, &dst_st.crtl_stat) == 0) {
- d_sts = mp_do_kill_file(NULL, dst_st.st_devnam, 0);
+ d_sts = mp_do_kill_file(aTHX_ dst_st.st_devnam, 0);
if (d_sts != 0)
break;
i++;
/* If the dest is a directory, we must remove it
if (dst_sts == 0) {
int d_sts;
- d_sts = mp_do_kill_file(NULL dst_st.st_devnam, 1);
+ d_sts = mp_do_kill_file(aTHX_ dst_st.st_devnam, 1);
if (d_sts != 0) {
PerlMem_free(vms_dst);
errno = EIO;
int i = 0;
dSAVEDERRNO;
SAVE_ERRNO;
- src_sts = mp_do_kill_file(NULL, src_st.st_devnam,
+ src_sts = mp_do_kill_file(aTHX_ src_st.st_devnam,
S_ISDIR(src_st.st_mode));
while (lstat(src_st.st_devnam, &src_st.crtl_stat) == 0) {
- src_sts = mp_do_kill_file(NULL, src_st.st_devnam,
+ src_sts = mp_do_kill_file(aTHX_ src_st.st_devnam,
S_ISDIR(src_st.st_mode));
if (src_sts != 0)
break;
if ((opts & PERL_RMSEXPAND_M_VMS) == 0)
#if !defined(__VAX) && defined(NAML$C_MAXRSS)
opts |= PERL_RMSEXPAND_M_LONG;
+#else
+ NOOP;
#endif
else
isunix = 0;
/* Is a long or a short name expected */
/*------------------------------------*/
spec_buf = NULL;
+#if !defined(__VAX) && defined(NAML$C_MAXRSS)
if ((opts & PERL_RMSEXPAND_M_LONG) != 0) {
if (rms_nam_rsll(mynam)) {
spec_buf = outbufl;
}
}
else {
+#endif
if (rms_nam_rsl(mynam)) {
spec_buf = outbuf;
speclen = rms_nam_rsl(mynam);
spec_buf = esa; /* Not esal */
speclen = rms_nam_esl(mynam);
}
+#if !defined(__VAX) && defined(NAML$C_MAXRSS)
}
+#endif
spec_buf[speclen] = '\0';
/* Trim off null fields added by $PARSE
}
/* Make sure we are using the right buffer */
+#if !defined(__VAX) && defined(NAML$C_MAXRSS)
if (esal != NULL) {
my_esa = esal;
my_esa_len = rms_nam_esll(dirnam);
} else {
+#endif
my_esa = esa;
my_esa_len = rms_nam_esl(dirnam);
+#if !defined(__VAX) && defined(NAML$C_MAXRSS)
}
+#endif
my_esa[my_esa_len] = '\0';
if (!rms_is_nam_fnb(dirnam, (NAM$M_EXP_DEV | NAM$M_EXP_DIR))) {
cp1 = strchr(my_esa,']');
}
if (*cp2 == ':') {
*(cp1++) = '/';
- if (*(cp2+1) == '[') cp2++;
+ if (*(cp2+1) == '[' || *(cp2+1) == '<') cp2++;
}
else if (*cp2 == ']' || *cp2 == '>') {
if (*(cp1-1) != '/') *(cp1++) = '/'; /* Don't double after ellipsis */
* special device files.
*/
- if ((add_6zero == 0) && (*nextslash == '/') &&
+ if (!islnm && (add_6zero == 0) && (*nextslash == '/') &&
(&nextslash[1] == unixend)) {
/* No real directory present */
add_6zero = 1;
vmsptr2 = vmsptr - 1;
if ((vmslen > 1) &&
(*vmsptr2 != ']') && (*vmsptr2 != '*') && (*vmsptr2 != '%') &&
- (*vmsptr2 != ')') && (*lastdot != '.')) {
+ (*vmsptr2 != ')') && (*lastdot != '.') && (*vmsptr2 != ':')) {
*vmsptr++ = '.';
vmslen++;
}
}
}
-/* If POSIX mode active, handle the conversion */
+/* If EFS charset mode active, handle the conversion */
#if __CRTL_VER >= 80200000 && !defined(__VAX)
if (decc_efs_charset) {
posix_to_vmsspec_hardway(rslt, rslt_len, path, dir_flag, utf8_flag);
/* Input from a pipe, reopen it in binary mode to disable */
/* carriage control processing. */
- fgetname(stdin, mbxname);
+ fgetname(stdin, mbxname, 1);
mbxnam.dsc$a_pointer = mbxname;
mbxnam.dsc$w_length = strlen(mbxnam.dsc$a_pointer);
lib$getdvi(&dvi_item, 0, &mbxnam, &bufsize, 0, 0);
Perl_csighandler_init();
#endif
+#if __CRTL_VER >= 70300000 && !defined(__VAX)
/* This was moved from the pre-image init handler because on threaded */
/* Perl it was always returning 0 for the default value. */
status = simple_trnlnm("SYS$POSIX_ROOT", eqv, LNM$C_NAMLENGTH);
}
}
}
-
+#endif
_ckvmssts_noperl(sys$getjpiw(0,NULL,NULL,jpilist,iosb,NULL,NULL));
_ckvmssts_noperl(iosb[0]);
/* In Unix report mode, remove the ".dir;1" from the name */
/* if it is a real directory. */
if (decc_filename_unix_report || decc_efs_charset) {
- if ((e_len == 4) && (vs_len == 2) && (vs_spec[1] == '1')) {
- if ((toupper(e_spec[1]) == 'D') &&
- (toupper(e_spec[2]) == 'I') &&
- (toupper(e_spec[3]) == 'R')) {
- Stat_t statbuf;
- int ret_sts;
-
- ret_sts = stat(buff, &statbuf.crtl_stat);
- if ((ret_sts == 0) && S_ISDIR(statbuf.st_mode)) {
- e_len = 0;
- e_spec[0] = 0;
- }
+ if (is_dir_ext(e_spec, e_len, vs_spec, vs_len)) {
+ Stat_t statbuf;
+ int ret_sts;
+
+ ret_sts = flex_lstat(buff, &statbuf);
+ if ((ret_sts == 0) && S_ISDIR(statbuf.st_mode)) {
+ e_len = 0;
+ e_spec[0] = 0;
}
}
}
int
my_fwrite(const void *src, size_t itmsz, size_t nitm, FILE *dest)
{
- register char *cp, *end, *cpd, *data;
+ register char *cp, *end, *cpd;
+ char *data;
register unsigned int fd = fileno(dest);
register unsigned int fdoff = fd / sizeof(unsigned int);
int retval;
}
/*}}}*/
+/* fgetname() is not returning the correct file specifications when
+ * decc_filename_unix_report mode is active. So we have to have it
+ * aways return filenames in VMS mode and convert it ourselves.
+ */
+
+/*{{{ char * my_fgetname(FILE *fp, buf)*/
+char *
+Perl_my_fgetname(FILE *fp, char * buf) {
+ char * retname;
+ char * vms_name;
+
+ retname = fgetname(fp, buf, 1);
+
+ /* If we are in VMS mode, then we are done */
+ if (!decc_filename_unix_report || (retname == NULL)) {
+ return retname;
+ }
+
+ /* Convert this to Unix format */
+ vms_name = PerlMem_malloc(VMS_MAXRSS + 1);
+ strcpy(vms_name, retname);
+ retname = int_tounixspec(vms_name, buf, NULL);
+ PerlMem_free(vms_name);
+
+ return retname;
+}
+/*}}}*/
+
/*
* Here are replacements for the following Unix routines in the VMS environment:
* getpwuid Get information for a particular UIC or UID
static int
Perl_flex_stat_int(pTHX_ const char *fspec, Stat_t *statbufp, int lstat_flag);
+#define flex_stat_int(a,b,c) Perl_flex_stat_int(aTHX_ a,b,c)
+
static I32
Perl_cando_by_name_int
(pTHX_ I32 bit, bool effective, const char *fname, int opts)
if (vmsname[retlen-1] == ']'
|| vmsname[retlen-1] == '>'
|| vmsname[retlen-1] == ':'
- || (!Perl_flex_stat_int(NULL, vmsname, &st, 1) &&
+ || (!flex_stat_int(vmsname, &st, 1) &&
S_ISDIR(st.st_mode))) {
if (!int_fileify_dirspec(vmsname, fileified, NULL)) {
} /* end of flex_fstat() */
/*}}}*/
-#if !defined(__VAX) && __CRTL_VER >= 80200000
-#ifdef lstat
-#undef lstat
-#endif
-#else
-#ifdef lstat
-#undef lstat
-#endif
-#define lstat(_x, _y) stat(_x, _y)
-#endif
-
-#define flex_stat_int(a,b,c) Perl_flex_stat_int(aTHX_ a,b,c)
-
static int
Perl_flex_stat_int(pTHX_ const char *fspec, Stat_t *statbufp, int lstat_flag)
{
if (SvTYPE(mysv) == SVt_PVGV) {
if (!(io = GvIOp(mysv)) || !PerlIO_getname(IoIFP(io),inspec)) {
set_errno(EINVAL); set_vaxc_errno(LIB$_INVARG);
- ST(0) = &PL_sv_no;
+ ST(0) = sv_2mortal(newSViv(0));
Safefree(inspec);
XSRETURN(1);
}
else {
if (mysv != ST(0) || !(inp = SvPV(mysv,n_a)) || !*inp) {
set_errno(EINVAL); set_vaxc_errno(LIB$_INVARG);
- ST(0) = &PL_sv_no;
+ ST(0) = sv_2mortal(newSViv(0));
Safefree(inspec);
XSRETURN(1);
}
if (SvTYPE(mysv) == SVt_PVGV) {
if (!(io = GvIOp(mysv)) || !PerlIO_getname(IoIFP(io),outspec)) {
set_errno(EINVAL); set_vaxc_errno(LIB$_INVARG);
- ST(0) = &PL_sv_no;
+ ST(0) = sv_2mortal(newSViv(0));
Safefree(inspec);
Safefree(outspec);
XSRETURN(1);
else {
if (mysv != ST(1) || !(outp = SvPV(mysv,n_a)) || !*outp) {
set_errno(EINVAL); set_vaxc_errno(LIB$_INVARG);
- ST(0) = &PL_sv_no;
+ ST(0) = sv_2mortal(newSViv(0));
Safefree(inspec);
Safefree(outspec);
XSRETURN(1);
}
date_flag = (items == 3) ? SvIV(ST(2)) : 0;
- ST(0) = boolSV(rmscopy(inp,outp,date_flag));
+ ST(0) = sv_2mortal(newSViv(rmscopy(inp,outp,date_flag)));
Safefree(inspec);
Safefree(outspec);
XSRETURN(1);
/* As symbolic links can hold things other than files, we will only do */
/* the conversion in in ODS-2 mode */
- Newx(utarget, VMS_MAXRSS + 1, char);
+ utarget = PerlMem_malloc(VMS_MAXRSS + 1);
if (int_tounixspec(contents, utarget, NULL) == NULL) {
/* This should not fail, as an untranslatable filename */
utarget = (char *)contents;
}
sts = symlink(utarget, link_name);
- Safefree(utarget);
+ PerlMem_free(utarget);
return sts;
}
int file_len = v_len + r_len + d_len + n_len + e_len;
vms_spec[file_len] = 0;
+ /* Trim off the .DIR if this is a directory */
+ if (is_dir_ext(e_spec, e_len, vs_spec, vs_len)) {
+ if (S_ISDIR(my_mode)) {
+ e_len = 0;
+ e_spec[0] = 0;
+ }
+ }
+
+ /* Drop NULL extensions on UNIX file specification */
+ if ((e_len == 1) && decc_readdir_dropdotnotype) {
+ e_len = 0;
+ e_spec[0] = '\0';
+ }
+
/* The result is expected to be in UNIX format */
rslt = int_tounixspec(vms_spec, outbuf, utf8_fl);