+/* Move the file descriptor FD so that its number is not less than MIN.
+ If the file descriptor is moved at all, the original is freed. */
+int
+relocate_fd (fd, min)
+ int fd, min;
+{
+ if (fd >= min)
+ return fd;
+ else
+ {
+ int new = dup (fd);
+ if (new == -1)
+ {
+ char *message1 = "Error while setting up child: ";
+ char *message2 = "\n";
+ write (2, message1, strlen (message1));
+ write (2, sys_errlist[errno], strlen (sys_errlist[errno]));
+ write (2, message2, strlen (message2));
+ _exit (1);
+ }
+ /* Note that we hold the original FD open while we recurse,
+ to guarantee we'll get a new FD if we need it. */
+ new = relocate_fd (new, min);
+ close (fd);
+ return new;
+ }
+}
+
+static int
+getenv_internal (var, varlen, value, valuelen)
+ char *var;
+ int varlen;
+ char **value;
+ int *valuelen;
+{
+ Lisp_Object scan;
+
+ for (scan = Vprocess_environment; CONSP (scan); scan = XCONS (scan)->cdr)
+ {
+ Lisp_Object entry = XCONS (scan)->car;
+
+ if (XTYPE (entry) == Lisp_String
+ && XSTRING (entry)->size > varlen
+ && XSTRING (entry)->data[varlen] == '='
+ && ! bcmp (XSTRING (entry)->data, var, varlen))
+ {
+ *value = (char *) XSTRING (entry)->data + (varlen + 1);
+ *valuelen = XSTRING (entry)->size - (varlen + 1);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+DEFUN ("getenv", Fgetenv, Sgetenv, 1, 2, 0,
+ "Return the value of environment variable VAR, as a string.\n\
+VAR should be a string. Value is nil if VAR is undefined in the environment.\n\
+This function consults the variable ``process-environment'' for its value.")
+ (var)
+ Lisp_Object var;
+{
+ char *value;
+ int valuelen;
+
+ CHECK_STRING (var, 0);
+ if (getenv_internal (XSTRING (var)->data, XSTRING (var)->size,
+ &value, &valuelen))
+ return make_string (value, valuelen);
+ else
+ return Qnil;
+}
+
+/* A version of getenv that consults process_environment, easily
+ callable from C. */
+char *
+egetenv (var)
+ char *var;
+{
+ char *value;
+ int valuelen;
+
+ if (getenv_internal (var, strlen (var), &value, &valuelen))
+ return value;
+ else
+ return 0;
+}
+