summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hints/solaris_2.sh17
-rw-r--r--opcode.h4
-rwxr-xr-xopcode.pl4
-rw-r--r--perl.h4
-rw-r--r--perlio.c9
-rw-r--r--unixish.h2
-rw-r--r--util.c132
7 files changed, 107 insertions, 65 deletions
diff --git a/hints/solaris_2.sh b/hints/solaris_2.sh
index 4668eddd42..d4549e3acb 100644
--- a/hints/solaris_2.sh
+++ b/hints/solaris_2.sh
@@ -638,13 +638,26 @@ EOOVER
rm -f try.c try.o try a.out
-# If using g++, the Configure scan for dlopen() will fail in Solaris
+# If using C++, the Configure scan for dlopen() will fail in Solaris
# because one of the two (1) an extern "C" linkage definition is needed
# (2) #include <dlfcn.h> is needed, *and* a cast to (void*(*)())
# is needed for the &dlopen. Adding any of these would require changing
# a delicate spot in Configure, so easier just to force our guess here
# for Solaris.
case "$cc" in
-*g++*) d_dlopen='define' ;;
+*g++*|/opt/SUNWspro/bin/CC) d_dlopen='define' ;;
+esac
+
+# The Sun C++ doesn't define the global environ array.
+case "$cc" in
+/opt/SUNWspro/bin/CC)
+ for o in NO_ENVIRON_ARRAY PERL_USE_SAFE_PUTENV
+ do
+ case "$ccflags" in
+ *$o*) ;;
+ *) ccflags="$ccflags $o" ;;
+ esac
+ done
+ ;;
esac
diff --git a/opcode.h b/opcode.h
index 6dd31c3810..4b32c85f31 100644
--- a/opcode.h
+++ b/opcode.h
@@ -1535,9 +1535,9 @@ EXT Perl_check_t PL_check[] /* or perlvars.h */
#ifndef PERL_GLOBAL_STRUCT_INIT
#ifndef DOINIT
-EXT const U32 PL_opargs[];
+EXTCONST U32 PL_opargs[];
#else
-EXT const U32 PL_opargs[] = {
+EXTCONST U32 PL_opargs[] = {
0x00000000, /* null */
0x00000000, /* stub */
0x00003604, /* scalar */
diff --git a/opcode.pl b/opcode.pl
index 3316fd9a9f..7098f131e4 100755
--- a/opcode.pl
+++ b/opcode.pl
@@ -287,9 +287,9 @@ print <<END;
#ifndef PERL_GLOBAL_STRUCT_INIT
#ifndef DOINIT
-EXT const U32 PL_opargs[];
+EXTCONST U32 PL_opargs[];
#else
-EXT const U32 PL_opargs[] = {
+EXTCONST U32 PL_opargs[] = {
END
%argnum = (
diff --git a/perl.h b/perl.h
index 9ae17aa2ef..5dab0f8ebf 100644
--- a/perl.h
+++ b/perl.h
@@ -1157,6 +1157,10 @@ EXTERN_C int fseeko(FILE *, off_t, int);
EXTERN_C off_t ftello(FILE *);
#endif
+#if defined(__SUNPRO_CC)
+EXTERN_C char *crypt(const char *, const char *);
+#endif
+
#ifdef SETERRNO
# undef SETERRNO /* SOCKS might have defined this */
#endif
diff --git a/perlio.c b/perlio.c
index b6dca82fb1..8f6947faf0 100644
--- a/perlio.c
+++ b/perlio.c
@@ -4593,7 +4593,14 @@ PerlIOMmap_unmap(pTHX_ PerlIO *f)
if (m->len) {
PerlIOBuf * const b = &m->base;
if (b->buf) {
- code = munmap(m->mptr, m->len);
+ /* The munmap address argument is tricky: depending on the
+ * standard it is either "void *" or "caddr_t" (which is
+ * usually "char *" (signed or unsigned). If we cast it
+ * to "void *", those that have it caddr_t and an uptight
+ * C++ compiler, will freak out. But casting it as char*
+ * should work. Maybe. (Using Mmap_t figured out by
+ * Configure doesn't always work, apparently.) */
+ code = munmap((char*)m->mptr, m->len);
b->buf = NULL;
m->len = 0;
m->mptr = NULL;
diff --git a/unixish.h b/unixish.h
index f464d8302b..631a619a1d 100644
--- a/unixish.h
+++ b/unixish.h
@@ -138,5 +138,7 @@
#define dXSUB_SYS
+#ifndef NO_ENVIRON_ARRAY
#define USE_ENVIRON_ARRAY
+#endif
diff --git a/util.c b/util.c
index 7a89c5cb32..44ff36ffe1 100644
--- a/util.c
+++ b/util.c
@@ -1557,8 +1557,7 @@ Perl_new_warnings_bitfield(pTHX_ STRLEN *buffer, const char *const bits,
*(s+(nlen+1+vlen)) = '\0'
#ifdef USE_ENVIRON_ARRAY
- /* VMS' my_setenv() is in vms.c */
-#if !defined(WIN32) && !defined(NETWARE)
+/* VMS' my_setenv() is in vms.c */
void
Perl_my_setenv(pTHX_ const char *nam, const char *val)
{
@@ -1570,47 +1569,53 @@ Perl_my_setenv(pTHX_ const char *nam, const char *val)
{
#ifndef PERL_USE_SAFE_PUTENV
if (!PL_use_safe_putenv) {
- /* most putenv()s leak, so we manipulate environ directly */
- register I32 i=setenv_getix(nam); /* where does it go? */
- int nlen, vlen;
-
- if (environ == PL_origenviron) { /* need we copy environment? */
- I32 j;
- I32 max;
- char **tmpenv;
-
- max = i;
- while (environ[max])
- max++;
- tmpenv = (char**)safesysmalloc((max+2) * sizeof(char*));
- for (j=0; j<max; j++) { /* copy environment */
- const int len = strlen(environ[j]);
- tmpenv[j] = (char*)safesysmalloc((len+1)*sizeof(char));
- Copy(environ[j], tmpenv[j], len+1, char);
- }
- tmpenv[max] = NULL;
- environ = tmpenv; /* tell exec where it is now */
- }
- if (!val) {
- safesysfree(environ[i]);
- while (environ[i]) {
- environ[i] = environ[i+1];
- i++;
+ /* The excuse for this code was that many putenv()s used to
+ * leak, so we manipulate environ directly -- but the claim is
+ * somewhat doubtful, since manipulating environment CANNOT be
+ * made in a safe way, the env API and the whole concept are
+ * fundamentally broken. */
+ register I32 i = setenv_getix(nam); /* where does it go? */
+ int nlen, vlen;
+
+ if (i >= 0) {
+ if (environ == PL_origenviron) { /* need we copy environment? */
+ I32 j;
+ I32 max;
+ char **tmpenv;
+
+ max = i;
+ while (environ[max])
+ max++;
+ tmpenv = (char**)safesysmalloc((max+2) * sizeof(char*));
+ for (j=0; j<max; j++) { /* copy environment */
+ const int len = strlen(environ[j]);
+ tmpenv[j] = (char*)safesysmalloc((len+1)*sizeof(char));
+ Copy(environ[j], tmpenv[j], len+1, char);
+ }
+ tmpenv[max] = NULL;
+ environ = tmpenv; /* tell exec where it is now */
+ }
+ if (!val) {
+ safesysfree(environ[i]);
+ while (environ[i]) {
+ environ[i] = environ[i+1];
+ i++;
+ }
+ return;
+ }
+ if (!environ[i]) { /* does not exist yet */
+ environ = (char**)safesysrealloc(environ, (i+2) * sizeof(char*));
+ environ[i+1] = NULL; /* make sure it's null terminated */
+ }
+ else
+ safesysfree(environ[i]);
+ nlen = strlen(nam);
+ vlen = strlen(val);
+
+ environ[i] = (char*)safesysmalloc((nlen+vlen+2) * sizeof(char));
+ /* all that work just for this */
+ my_setenv_format(environ[i], nam, nlen, val, vlen);
}
- return;
- }
- if (!environ[i]) { /* does not exist yet */
- environ = (char**)safesysrealloc(environ, (i+2) * sizeof(char*));
- environ[i+1] = NULL; /* make sure it's null terminated */
- }
- else
- safesysfree(environ[i]);
- nlen = strlen(nam);
- vlen = strlen(val);
-
- environ[i] = (char*)safesysmalloc((nlen+vlen+2) * sizeof(char));
- /* all that work just for this */
- my_setenv_format(environ[i], nam, nlen, val, vlen);
} else {
# endif
# if defined(__CYGWIN__) || defined(EPOC) || defined(__SYMBIAN32__) || defined(__riscos__)
@@ -1655,36 +1660,46 @@ Perl_my_setenv(pTHX_ const char *nam, const char *val)
}
}
-#else /* WIN32 || NETWARE */
+#else /* USE_ENVIRON_ARRAY */
void
Perl_my_setenv(pTHX_ const char *nam, const char *val)
{
dVAR;
- register char *envstr;
- const int nlen = strlen(nam);
- int vlen;
+#if !(defined(WIN32) || defined(NETWARE))
+# ifdef USE_ITHREADS
+ /* only parent thread can modify process environment */
+ if (PL_curinterp == aTHX)
+# endif
+#endif
+ {
+ register char *envstr;
+ const int nlen = strlen(nam);
+ int vlen;
- if (!val) {
- val = "";
+ if (!val) {
+ val = "";
+ }
+ vlen = strlen(val);
+ Newx(envstr, nlen+vlen+2, char);
+ my_setenv_format(envstr, nam, nlen, val, vlen);
+ (void)PerlEnv_putenv(envstr);
+ Safefree(envstr);
}
- vlen = strlen(val);
- Newx(envstr, nlen+vlen+2, char);
- my_setenv_format(envstr, nam, nlen, val, vlen);
- (void)PerlEnv_putenv(envstr);
- Safefree(envstr);
}
-#endif /* WIN32 || NETWARE */
+#endif /* USE_ENVIRON_ARRAY */
+
+#if !defined(VMS)
-#ifndef PERL_MICRO
I32
Perl_setenv_getix(pTHX_ const char *nam)
{
- register I32 i;
+ register I32 i = -1;
register const I32 len = strlen(nam);
PERL_UNUSED_CONTEXT;
+#ifdef USE_ENVIRON_ARRAY
for (i = 0; environ[i]; i++) {
if (
#ifdef WIN32
@@ -1695,11 +1710,12 @@ Perl_setenv_getix(pTHX_ const char *nam)
&& environ[i][len] == '=')
break; /* strnEQ must come first to avoid */
} /* potential SEGV's */
+#endif /* USE_ENVIRON_ARRAY */
+
return i;
}
-#endif /* !PERL_MICRO */
-#endif /* !VMS && !EPOC*/
+#endif /* !PERL_VMS */
#ifdef UNLINK_ALL_VERSIONS
I32