C++: Solaris CC now compiles "perl"
Jarkko Hietaniemi [Sat, 9 Sep 2006 15:29:12 +0000 (18:29 +0300)]
Message-ID: <4502B398.6060505@iki.fi>

p4raw-id: //depot/perl@28814

hints/solaris_2.sh
opcode.h
opcode.pl
perl.h
perlio.c
unixish.h
util.c

index 4668edd..d4549e3 100644 (file)
@@ -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
 
index 6dd31c3..4b32c85 100644 (file)
--- 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 */
index 3316fd9..7098f13 100755 (executable)
--- 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 9ae17aa..5dab0f8 100644 (file)
--- 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
index b6dca82..8f6947f 100644 (file)
--- 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;
index f464d83..631a619 100644 (file)
--- a/unixish.h
+++ b/unixish.h
 
 #define dXSUB_SYS
 
+#ifndef NO_ENVIRON_ARRAY
 #define USE_ENVIRON_ARRAY
+#endif
 
diff --git a/util.c b/util.c
index 7a89c5c..44ff36f 100644 (file)
--- 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