{LNM$C_NAMLENGTH, LNM$_STRING, eqv, &eqvlen},
{0, 0, 0, 0}};
$DESCRIPTOR(crtlenv,"CRTL_ENV"); $DESCRIPTOR(clisym,"CLISYM");
+#if defined(USE_THREADS)
+ /* We jump through these hoops because we can be called at */
+ /* platform-specific initialization time, which is before anything is */
+ /* set up--we can't even do a plain dTHR since that relies on the */
+ /* interpreter structure to be initialized */
+ struct perl_thread *thr;
+ if (PL_curinterp) {
+ thr = PL_threadnum? THR : (struct perl_thread*)SvPVX(PL_thrsv);
+ } else {
+ thr = NULL;
+ }
+#endif
if (!lnm || !eqv || idx > LNM$_MAX_INDEX) {
set_errno(EINVAL); set_vaxc_errno(SS$_BADPARAM); return 0;
if (eqvlen > 1024) {
set_errno(EVMSERR); set_vaxc_errno(LIB$_STRTRU);
eqvlen = 1024;
- if (ckWARN(WARN_MISC))
- warner(WARN_MISC,"Value of CLI symbol \"%s\" too long",lnm);
+ /* Special hack--we might be called before the interpreter's */
+ /* fully initialized, in which case either thr or PL_curcop */
+ /* might be bogus. We have to check, since ckWARN needs them */
+ /* both to be valid if running threaded */
+#if defined(USE_THREADS)
+ if (thr && PL_curcop) {
+#endif
+ if (ckWARN(WARN_MISC)) {
+ warner(WARN_MISC,"Value of CLI symbol \"%s\" too long",lnm);
+ }
+#if defined(USE_THREADS)
+ } else {
+ warner(WARN_MISC,"Value of CLI symbol \"%s\" too long",lnm);
+ }
+#endif
+
}
strncpy(eqv,eqvdsc.dsc$a_pointer,eqvlen);
}
} /* end of vmstrnenv */
/*}}}*/
-
/*{{{ int my_trnlnm(const char *lnm, char *eqv, unsigned long int idx)*/
/* Define as a function so we can access statics. */
int my_trnlnm(const char *lnm, char *eqv, unsigned long int idx)
* Note: Uses Perl temp to store result so char * can be returned to
* caller; this pointer will be invalidated at next Perl statement
* transition.
- * We define this as a function rather than a macro in terms of my_getenv_sv()
+ * We define this as a function rather than a macro in terms of my_getenv_len()
* so that it'll work when PL_curinterp is undefined (and we therefore can't
* allocate SVs).
*/
/*}}}*/
-/*{{{ SV *my_getenv_sv(const char *lnm, bool sys)*/
-SV *
-my_getenv_sv(const char *lnm, bool sys)
+/*{{{ SV *my_getenv_len(const char *lnm, bool sys)*/
+char *
+my_getenv_len(const char *lnm, unsigned long *len, bool sys)
{
- char buf[LNM$C_NAMLENGTH+1], *cp1, *cp2;
- unsigned long int len, idx = 0;
-
+ char *buf, *cp1, *cp2;
+ unsigned long idx = 0;
+ static char __my_getenv_len_eqv[LNM$C_NAMLENGTH+1];
+ SV *tmpsv;
+
+ if (PL_curinterp) { /* Perl interpreter running -- may be threaded */
+ /* Set up a temporary buffer for the return value; Perl will
+ * clean it up at the next statement transition */
+ tmpsv = sv_2mortal(newSVpv("",LNM$C_NAMLENGTH+1));
+ if (!tmpsv) return NULL;
+ buf = SvPVX(tmpsv);
+ }
+ else buf = __my_getenv_len_eqv; /* Assume no interpreter ==> single thread */
for (cp1 = (char *)lnm, cp2 = buf; *cp1; cp1++,cp2++) *cp2 = _toupper(*cp1);
if (cp1 - lnm == 7 && !strncmp(buf,"DEFAULT",7)) {
getcwd(buf,LNM$C_NAMLENGTH);
- return newSVpv(buf,0);
+ *len = strlen(buf);
+ return buf;
}
else {
if ((cp2 = strchr(lnm,';')) != NULL) {
idx = strtoul(cp2+1,NULL,0);
lnm = buf;
}
- if ((len = vmstrnenv(lnm,buf,idx,
+ if ((*len = vmstrnenv(lnm,buf,idx,
sys ? fildev : NULL,
#ifdef SECURE_INTERNAL_GETENV
sys ? PERL__TRNENV_SECURE : 0
#else
0
#endif
- ))) return newSVpv(buf,len);
- else return &PL_sv_undef;
+ )))
+ return buf;
+ else
+ return Nullch;
}
-} /* end of my_getenv_sv() */
+} /* end of my_getenv_len() */
/*}}}*/
static void create_mbx(unsigned short int *, struct dsc$descriptor_s *);
key = cp1; keylen = cp2 - cp1;
if (keylen && hv_exists(seenhv,key,keylen)) continue;
while (*cp2 && *cp2 != '=') cp2++;
- while (*cp2 && *cp2 != '"') cp2++;
- for (cp1 = buf + retlen; *cp1 != '"'; cp1--) ;
- if ((!keylen || (cp1 - cp2 <= 0)) && ckWARN(WARN_INTERNAL)) {
+ while (*cp2 && *cp2 == '=') cp2++;
+ while (*cp2 && *cp2 == ' ') cp2++;
+ if (*cp2 == '"') { /* String translation; may embed "" */
+ for (cp1 = buf + retlen; *cp1 != '"'; cp1--) ;
+ cp2++; cp1--; /* Skip "" surrounding translation */
+ }
+ else { /* Numeric translation */
+ for (cp1 = cp2; *cp1 && *cp1 != ' '; cp1++) ;
+ cp1--; /* stop on last non-space char */
+ }
+ if ((!keylen || (cp1 - cp2 < -1)) && ckWARN(WARN_INTERNAL)) {
warner(WARN_INTERNAL,"Ill-formed message in prime_env_iter: |%s|",buf);
continue;
}
- /* Skip "" surrounding translation */
PERL_HASH(hash,key,keylen);
- hv_store(envhv,key,keylen,newSVpv(cp2+1,cp1 - cp2 - 1),hash);
+ hv_store(envhv,key,keylen,newSVpvn(cp2,cp1 - cp2 + 1),hash);
hv_store(seenhv,key,keylen,&PL_sv_yes,hash);
}
if (cmddsc.dsc$w_length == 14) { /* We just read LNM$FILE_DEV */
* to a mbx; that's the caller's responsibility.
*/
static unsigned long int
-pipe_eof(FILE *fp)
+pipe_eof(FILE *fp, int immediate)
{
char devnam[NAM$C_MAXRSS+1], *cp;
unsigned long int chan, iosb[2], retsts, retsts2;
if ((cp = strrchr(devnam,':')) != NULL) *(cp+1) = '\0';
devdsc.dsc$w_length = strlen(devnam);
_ckvmssts(sys$assign(&devdsc,&chan,0,0));
- retsts = sys$qiow(0,chan,IO$_WRITEOF,iosb,0,0,0,0,0,0,0,0);
+ retsts = sys$qiow(0,chan,IO$_WRITEOF|(immediate?IO$M_NOW|IO$M_NORSWAIT:0),
+ iosb,0,0,0,0,0,0,0,0);
if (retsts & 1) retsts = iosb[0];
retsts2 = sys$dassgn(chan); /* Be sure to deassign the channel */
if (retsts & 1) retsts = retsts2;
while (info) {
if (info->mode != 'r' && !info->done) {
- if (pipe_eof(info->fp) & 1) did_stuff = 1;
+ if (pipe_eof(info->fp, 1) & 1) did_stuff = 1;
}
info = info->next;
}
/* If we were writing to a subprocess, insure that someone reading from
* the mailbox gets an EOF. It looks like a simple fclose() doesn't
* produce an EOF record in the mailbox. */
- if (info->mode != 'r' && !info->done) pipe_eof(info->fp);
+ if (info->mode != 'r' && !info->done) pipe_eof(info->fp,0);
PerlIO_close(info->fp);
if (info->done) retsts = info->completion;
my_waitpid(Pid_t pid, int *statusp, int flags)
{
struct pipe_details *info;
+ dTHR;
for (info = open_pipes; info != NULL; info = info->next)
if (info->pid == pid) break;
vms_do_exec(char *cmd)
{
+ dTHR;
if (vfork_called) { /* this follows a vfork - act Unixish */
vfork_called--;
if (vfork_called < 0) {
do_spawn(char *cmd)
{
unsigned long int sts, substs, hadcmd = 1;
+ dTHR;
TAINT_ENV();
TAINT_PROPER("spawn");
} /* end of flex_fstat() */
/*}}}*/
-/*{{{ int flex_stat(char *fspec, Stat_t *statbufp)*/
+/*{{{ int flex_stat(const char *fspec, Stat_t *statbufp)*/
int
-flex_stat(char *fspec, Stat_t *statbufp)
+flex_stat(const char *fspec, Stat_t *statbufp)
{
dTHR;
char fileified[NAM$C_MAXRSS+1];
+ char temp_fspec[NAM$C_MAXRSS+300];
int retval = -1;
+ strcpy(temp_fspec, fspec);
if (statbufp == (Stat_t *) &PL_statcache)
- do_tovmsspec(fspec,namecache,0);
- if (is_null_device(fspec)) { /* Fake a stat() for the null device */
+ do_tovmsspec(temp_fspec,namecache,0);
+ if (is_null_device(temp_fspec)) { /* Fake a stat() for the null device */
memset(statbufp,0,sizeof *statbufp);
statbufp->st_dev = encode_dev("_NLA0:");
statbufp->st_mode = S_IFBLK | S_IREAD | S_IWRITE | S_IEXEC;
* the file with null type, specify this by calling flex_stat() with
* a '.' at the end of fspec.
*/
- if (do_fileify_dirspec(fspec,fileified,0) != NULL) {
+ if (do_fileify_dirspec(temp_fspec,fileified,0) != NULL) {
retval = stat(fileified,(stat_t *) statbufp);
if (!retval && statbufp == (Stat_t *) &PL_statcache)
strcpy(namecache,fileified);
}
- if (retval) retval = stat(fspec,(stat_t *) statbufp);
+ if (retval) retval = stat(temp_fspec,(stat_t *) statbufp);
if (!retval) {
statbufp->st_dev = encode_dev(statbufp->st_devnam);
# ifdef RTL_USES_UTC