# 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;
+}