# New Ticket Created by  Lars Balker Rasmussen 
# Please include the string:  [perl #22925]
# in the subject line of all future correspondence about this issue. 
# <URL: http://rt.perl.org/rt2/Ticket/Display.html?id=22925 >


Since parrot currently can't compile on Solaris due to the absense of
setenv/unsetenv in the Solaris libc, I've added tests for the
functions, as well as a putenv-based implementation.

With this patch, parrot compiles on Solaris, and completes the
test-suite (ignoring the current manifest-error).
-- 
Lars Balker Rasmussen                                      Consult::Perl



-- attachment  1 ------------------------------------------------------
url: http://rt.perl.org/rt2/attach/60603/44854/549d21/env.patch

Index: config/gen/platform/ansi.c
===================================================================
RCS file: /cvs/public/parrot/config/gen/platform/ansi.c,v
retrieving revision 1.6
diff -u -a -r1.6 ansi.c
--- config/gen/platform/ansi.c	11 Jul 2003 17:49:46 -0000	1.6
+++ config/gen/platform/ansi.c	12 Jul 2003 18:20:41 -0000
@@ -44,33 +44,46 @@
 }
 
 
-/*
-** Parrot_setenv()
-*/
 void
 Parrot_setenv(const char *name, const char *value)
 {
-    Parrot_warn(NULL, PARROT_WARNINGS_PLATFORM_FLAG,
-            "Parrot_setenv not implemented");
-    return;
+#ifdef HAS_SETENV
+    setenv(name, value, 1);
+#else
+    int name_len = strlen(name);
+    int val_len = strlen(value);
+
+    char *envs = malloc(name_len + 1 + val_len + 1);
+    if (envs == NULL)
+        return;
+
+    /* Save a bit of time, by using the fact we already have the
+       lengths, avoiding strcat */
+    strcpy(envs, name);
+    strcpy(envs + name_len, "=");
+    strcpy(envs + name_len + 1, value);
+
+    putenv(envs);
+
+    /* The buffer is intentionally not freed! */
+#endif
 }
 
 void
 Parrot_unsetenv(const char *name)
 {
-    Parrot_warn(NULL, PARROT_WARNINGS_PLATFORM_FLAG,
-            "Parrot_unsetenv not implemented");
-    return;
+#ifdef HAS_UNSETENV
+    unsetenv(name);
+#else 
+    Parrot_setenv(name, "");
+#endif 
 }
 
 char *
 Parrot_getenv(const char *name)
 {
-    Parrot_warn(NULL, PARROT_WARNINGS_PLATFORM_FLAG,
-            "Parrot_getenv not implemented");
-    return;
+    return getenv(name);
 }
-
 
 /*
 ** Parrot_dlopen()
Index: config/gen/platform/darwin.c
===================================================================
RCS file: /cvs/public/parrot/config/gen/platform/darwin.c,v
retrieving revision 1.7
diff -u -a -r1.7 darwin.c
--- config/gen/platform/darwin.c	12 Jul 2003 17:45:04 -0000	1.7
+++ config/gen/platform/darwin.c	12 Jul 2003 18:20:41 -0000
@@ -62,28 +62,46 @@
 ** Parrot_setenv()
 */
 
-#define HAS_SETENV /* XXX need a test, this is never set */
-#ifdef HAS_SETENV
 void
 Parrot_setenv(const char *name, const char *value)
 {
+#ifdef HAS_SETENV
     setenv(name, value, 1);
+#else
+    int name_len = strlen(name);
+    int val_len = strlen(value);
+
+    char *envs = malloc(name_len + 1 + val_len + 1);
+    if (envs == NULL)
+        return;
+
+    /* Save a bit of time, by using the fact we already have the
+       lengths, avoiding strcat */
+    strcpy(envs, name);
+    strcpy(envs + name_len, "=");
+    strcpy(envs + name_len + 1, value);
+
+    putenv(envs);
+
+    /* The buffer is intentionally not freed! */
+#endif
 }
+
 void
 Parrot_unsetenv(const char *name)
 {
+#ifdef HAS_UNSETENV
     unsetenv(name);
+#else 
+    Parrot_setenv(name, "");
+#endif 
 }
+
 char *
 Parrot_getenv(const char *name)
 {
     return getenv(name);
 }
-#else
-/* putenv-based version might go here, but see perl5's util.c for
-   warnings and workarounds.
-*/
-#endif
 
 /*
 ** Parrot_dlopen()
Index: config/gen/platform/generic.c
===================================================================
RCS file: /cvs/public/parrot/config/gen/platform/generic.c,v
retrieving revision 1.13
diff -u -a -r1.13 generic.c
--- config/gen/platform/generic.c	12 Jul 2003 17:45:04 -0000	1.13
+++ config/gen/platform/generic.c	12 Jul 2003 18:20:41 -0000
@@ -64,18 +64,39 @@
 ** Parrot_setenv()
 */
 
-#define HAS_SETENV /* XXX need a test, this is never set */
-#ifdef HAS_SETENV
 void
 Parrot_setenv(const char *name, const char *value)
 {
+#ifdef HAS_SETENV
     setenv(name, value, 1);
+#else
+    int name_len = strlen(name);
+    int val_len = strlen(value);
+
+    char *envs = malloc(name_len + 1 + val_len + 1);
+    if (envs == NULL)
+        return;
+
+    /* Save a bit of time, by using the fact we already have the
+       lengths, avoiding strcat */
+    strcpy(envs, name);
+    strcpy(envs + name_len, "=");
+    strcpy(envs + name_len + 1, value);
+
+    putenv(envs);
+
+    /* The buffer is intentionally not freed! */
+#endif
 }
 
 void
 Parrot_unsetenv(const char *name)
 {
+#ifdef HAS_UNSETENV
     unsetenv(name);
+#else 
+    Parrot_setenv(name, "");
+#endif 
 }
 
 char *
@@ -83,12 +104,6 @@
 {
     return getenv(name);
 }
-#else
-/* putenv-based version might go here, but see perl5's util.c for
-   warnings and workarounds.
-*/
-#endif
-
 
 /*
 ** Parrot_dlopen()
Index: config/gen/feature_h/feature_h.in
===================================================================
RCS file: /cvs/public/parrot/config/gen/feature_h/feature_h.in,v
retrieving revision 1.8
diff -u -a -r1.8 feature_h.in
--- config/gen/feature_h/feature_h.in	11 Jul 2003 11:31:56 -0000	1.8
+++ config/gen/feature_h/feature_h.in	12 Jul 2003 18:20:41 -0000
@@ -3,8 +3,8 @@
  */
 
 
-#if !defined(PARROT_FEATRUE_H_GUARD)
-#define PARROT_FEATRUE_H_GUARD
+#if !defined(PARROT_FEATURE_H_GUARD)
+#define PARROT_FEATURE_H_GUARD
 
 #perl - all below here gets evaled by perl, OUT is the filehandle
 
@@ -70,6 +70,22 @@
 #define HAS___SIGHANDLER_T 1
 END
 }
+
+print OUT <<EOP;
+
+/* from config/auto/env */
+EOP
+if (${setenv}) {
+	print OUT <<EOP;
+#define HAS_SETENV 1
+EOP
+}
+if (${unsetenv}) {
+	print OUT <<EOP;
+#define HAS_UNSETENV 1
+EOP
+}
+
 
 #endif guard
 print OUT "\n\n#endif\n"
Index: lib/Parrot/Configure/RunSteps.pm
===================================================================
RCS file: /cvs/public/parrot/lib/Parrot/Configure/RunSteps.pm,v
retrieving revision 1.21
diff -u -a -r1.21 RunSteps.pm
--- lib/Parrot/Configure/RunSteps.pm	11 Jul 2003 11:32:02 -0000	1.21
+++ lib/Parrot/Configure/RunSteps.pm	12 Jul 2003 18:20:41 -0000
@@ -30,6 +30,7 @@
 	auto/gc.pl
 	auto/memalign.pl
 	auto/signal.pl
+	auto/env.pl
 	gen/config_h.pl
 	gen/feature_h.pl
 	gen/config_pm.pl
Index :config/auto/env.pl
===================================================================
diff -u -a /dev/null config/auto/env.pl
--- /dev/null	Sat Jul 12 20:22:00 2003
+++ config/auto/env.pl	Sat Jul 12 17:19:02 2003
@@ -0,0 +1,45 @@
+package Configure::Step;
+
+use strict;
+use vars qw($description @args);
+use Parrot::Configure::Step ':auto';
+
+$description="Determining if your C library has setenv / unsetenv...";
+
+sub runstep {
+    my ($setenv, $unsetenv) = (0, 0);
+
+    cc_gen('config/auto/env/test_setenv.in');
+    eval { cc_build(); };
+    unless ($@ || cc_run() !~ /ok/) {
+	$setenv = 1;
+    }
+    cc_clean();
+
+    cc_gen('config/auto/env/test_unsetenv.in');
+    eval { cc_build(); };
+    unless ($@ || cc_run() !~ /ok/) {
+	$unsetenv = 1;
+    }
+    cc_clean();
+
+    Configure::Data->set(
+	setenv => $setenv, 
+	unsetenv => $unsetenv
+    );
+
+    if ($setenv && $unsetenv) {
+	print " (both) ";
+    }
+    elsif ($setenv) {
+	print " (setenv) ";
+    }
+    elsif ($unsetenv) {
+	print " (unsetenv) ";
+    }
+    else {
+	print " (no) ";
+    }
+}
+
+1;
Index: config/auto/env/test_setenv.in
===================================================================
diff -u -a /dev/null config/auto/env/test_setenv.in
--- /dev/null	Sat Jul 12 20:22:00 2003
+++ config/auto/env/test_setenv.in	Sat Jul 12 17:10:44 2003
@@ -0,0 +1,17 @@
+/*
+ * test for setenv
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+int main(int argc, char **argv) {
+    if (setenv("PARROT_TEST", "flaf", 1)) {
+        puts("borken");
+    } else {
+        puts("ok");
+    }
+
+    return 0;
+}
Index: config/auto/env/test_unsetenv.in
===================================================================
diff -u -a /dev/null config/auto/env/test_unsetenv.in
--- /dev/null	Sat Jul 12 20:22:00 2003
+++ config/auto/env/test_unsetenv.in	Sat Jul 12 17:17:31 2003
@@ -0,0 +1,13 @@
+/*
+ * test for unsetenv
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+int main(int argc, char **argv) {
+    unsetenv("PARROT_TEST");
+    puts("ok");
+    return 0;
+}

Reply via email to