*** empty log message ***

This commit is contained in:
Jim Blandy 1992-01-14 08:05:08 +00:00
parent 2798dedf7c
commit efb859b44a
5 changed files with 201 additions and 235 deletions

View file

@ -1,4 +1,4 @@
/* Client process that communicates with GNU Emacs acting as server.`
/* Client process that communicates with GNU Emacs acting as server.
Copyright (C) 1986, 1987 Free Software Foundation, Inc.
This file is part of GNU Emacs.
@ -49,13 +49,10 @@ main (argc, argv)
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/stat.h>
#include <stdio.h>
#include <errno.h>
#ifndef SERVER_HOME_DIR
#include <sys/stat.h>
#endif
extern int sys_nerr;
extern char *sys_errlist[];
extern int errno;
@ -70,9 +67,6 @@ main (argc, argv)
struct sockaddr_un server;
char *homedir, *cwd, *str;
char string[BUFSIZ];
#ifndef SERVER_HOME_DIR
struct stat statbfr;
#endif
char *getenv (), *getwd ();
int geteuid ();
@ -95,19 +89,23 @@ main (argc, argv)
}
server.sun_family = AF_UNIX;
#ifndef SERVER_HOME_DIR
gethostname (system_name, sizeof (system_name));
sprintf (server.sun_path, "/tmp/esrv%d-%s", geteuid (), system_name);
{
struct stat statbfr;
if (stat (server.sun_path, &statbfr) == -1)
{
perror ("stat");
exit (1);
}
if (statbfr.st_uid != geteuid())
{
fprintf (stderr, "Illegal socket owner\n");
exit (1);
}
gethostname (system_name, sizeof (system_name));
sprintf (server.sun_path, "/tmp/esrv%d-%s", geteuid (), system_name);
if (stat (server.sun_path, &statbfr) == -1)
{
perror ("stat");
exit (1);
}
if (statbfr.st_uid != geteuid())
{
fprintf (stderr, "Illegal socket owner\n");
exit (1);
}
}
#else
if ((homedir = getenv ("HOME")) == NULL)
{

View file

@ -61,12 +61,7 @@ Lisp_Object Vexec_path, Vexec_directory, Vdata_directory;
Lisp_Object Vshell_file_name;
#ifndef MAINTAIN_ENVIRONMENT
/* List of strings to append to front of environment of
all subprocesses when they are started. */
Lisp_Object Vprocess_environment;
#endif
/* True iff we are about to fork off a synchronous process or if we
are waiting for it. */
@ -123,7 +118,7 @@ If you quit, the process is killed with SIGKILL.")
#endif
CHECK_STRING (args[0], 0);
if (nargs <= 1 || NULL (args[1]))
if (nargs <= 1 || NILP (args[1]))
args[1] = build_string ("/dev/null");
else
args[1] = Fexpand_file_name (args[1], current_buffer->directory);
@ -164,7 +159,7 @@ If you quit, the process is killed with SIGKILL.")
}
/* Search for program; barf if not found. */
openp (Vexec_path, args[0], "", &path, 1);
if (NULL (path))
if (NILP (path))
{
close (filefd);
report_file_error ("Searching for program", Fcons (args[0], Qnil));
@ -189,12 +184,7 @@ If you quit, the process is killed with SIGKILL.")
register int fd1 = fd[1];
char **env;
#ifdef MAINTAIN_ENVIRONMENT
env = (char **) alloca (size_of_current_environ ());
get_current_environ (env);
#else
env = environ;
#endif /* MAINTAIN_ENVIRONMENT */
#if 0 /* Some systems don't have sigblock. */
mask = sigblock (sigmask (SIGCHLD));
@ -260,9 +250,9 @@ If you quit, the process is killed with SIGKILL.")
while ((nread = read (fd[0], buf, sizeof buf)) > 0)
{
immediate_quit = 0;
if (!NULL (buffer))
if (!NILP (buffer))
insert (buf, nread);
if (!NULL (display) && INTERACTIVE)
if (!NILP (display) && INTERACTIVE)
redisplay_preserve_echo_area ();
immediate_quit = 1;
QUIT;
@ -324,7 +314,7 @@ If you quit, the process is killed with SIGKILL.")
Fwrite_region (start, end, filename_string, Qnil, Qlambda);
record_unwind_protect (delete_temp_file, filename_string);
if (!NULL (args[3]))
if (!NILP (args[3]))
Fdelete_region (start, end);
args[3] = filename_string;
@ -387,7 +377,6 @@ child_setup (in, out, err, new_argv, env, set_pgrp)
Fcons (current_buffer->directory, Qnil));
}
#ifndef MAINTAIN_ENVIRONMENT
/* Set `env' to a vector of the strings in Vprocess_environment. */
{
register Lisp_Object tem;
@ -412,7 +401,6 @@ child_setup (in, out, err, new_argv, env, set_pgrp)
*new_env++ = (char *) XSTRING (XCONS (tem)->car)->data;
*new_env = 0;
}
#endif /* Not MAINTAIN_ENVIRONMENT */
close (0);
close (1);
@ -442,6 +430,65 @@ child_setup (in, out, err, new_argv, env, set_pgrp)
_exit (1);
}
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 = 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 *value;
int valuelen;
if (getenv_internal (var, strlen (var), &value, &valuelen))
return value;
else
return 0;
}
#endif /* not VMS */
init_callproc ()
@ -477,13 +524,10 @@ init_callproc ()
#ifdef VMS
Vshell_file_name = build_string ("*dcl*");
#else
sh = (char *) egetenv ("SHELL");
sh = (char *) getenv ("SHELL");
Vshell_file_name = build_string (sh ? sh : "/bin/sh");
#endif
#ifndef MAINTAIN_ENVIRONMENT
/* The equivalent of this operation was done
in init_environ in environ.c if MAINTAIN_ENVIRONMENT */
Vprocess_environment = Qnil;
#ifndef CANNOT_DUMP
if (initialized)
@ -491,7 +535,6 @@ init_callproc ()
for (envp = environ; *envp; envp++)
Vprocess_environment = Fcons (build_string (*envp),
Vprocess_environment);
#endif /* MAINTAIN_ENVIRONMENT */
}
syms_of_callproc ()
@ -512,14 +555,15 @@ especially executable programs intended for Emacs to invoke.");
"Directory of architecture-independent files that come with GNU Emacs,\n\
intended for Emacs to use.");
#ifndef MAINTAIN_ENVIRONMENT
DEFVAR_LISP ("process-environment", &Vprocess_environment,
"List of strings to append to environment of subprocesses that are started.\n\
Each string should have the format ENVVARNAME=VALUE.");
#endif
"List of environment variables for subprocesses to inherit.\n\
Each element should be a string of the form ENVVARNAME=VALUE.\n\
The environment which Emacs inherits is placed in this variable\n\
when Emacs starts.");
#ifndef VMS
defsubr (&Scall_process);
#endif
defsubr (&Sgetenv);
defsubr (&Scall_process_region);
}

View file

@ -20,6 +20,79 @@ and this notice must be preserved on all copies. */
/* Define HAVE_X_WINDOWS if you want to use the X window system. */
/* #define HAVE_X_WINDOWS */
/* Define HAVE_X11 if you want to use version 11 of X windows.
Otherwise, Emacs expects to use version 10. */
/* #define HAVE_X11 */
/* Define HAVE_X_MENU if you want to use the X window menu system.
This appears to work on some machines that support X
and not on others. */
/* #define HAVE_X_MENU */
/* If we're using any sort of window system, define MULTI_SCREEN. */
#ifdef HAVE_X_WINDOWS
#define MULTI_SCREEN
#endif
/* Define USER_FULL_NAME to return a string
that is the user's full name.
It can assume that the variable `pw'
points to the password file entry for this user.
At some sites, the pw_gecos field contains
the user's full name. If neither this nor any other
field contains the right thing, use pw_name,
giving the user's login name, since that is better than nothing. */
#define USER_FULL_NAME pw->pw_gecos
/* Define AMPERSAND_FULL_NAME if you use the convention
that & in the full name stands for the login id. */
/* #define AMPERSAND_FULL_NAME */
/* Define HIGHPRI as a negative number
if you want Emacs to run at a higher than normal priority.
For this to take effect, you must install Emacs with setuid root.
Emacs will change back to the users's own uid after setting
its priority. */
/* #define HIGHPRI */
/* Define LISP_FLOAT_TYPE if you want emacs to support floating-point
numbers. */
/* #define LISP_FLOAT_TYPE */
/* Define GNU_MALLOC if you want to use the *new* GNU memory allocator. */
/* #define GNU_MALLOC */
/* Define REL_ALLOC if you want to use the relocating allocator for
buffer space. */
/* #define REL_ALLOC */
/* Define this macro if you want to use 16-bit GLYPHs. Currently this
option isn't terribly useful (the current distribution doesn't
support large characters in buffer text), so the configuration
script doesn't provide an option to select it.
A character is displayed on a given terminal by means of a sequence
of one or more GLYPHs. A GLYPH is something that takes up exactly
one display position on the screen.
Emacs can use 8-bit or 16-bit values to represent GLYPHs. Under X
windows, 16-bit GLYPHs allow you to display characters from fonts
too large to be indexed by 8 bits alone, but drawing with 16-bit GLYPHs
is usually quite a bit slower than drawing with 8-bit GLYPHs. */
/* #define GLYPH_16_BIT */
#ifdef GLYPH_16_BIT
#define GLYPH unsigned short
#else
#define GLYPH unsigned char
#endif
/* The configuration script links system.h to a s- file that describes
the system type you are using.
See the file ../share-lib/MACHINES for a list of systems and
@ -45,27 +118,6 @@ and this notice must be preserved on all copies. */
#endif /* not NO_SHORTNAMES */
#endif /* SHORTNAMES */
/* Define HAVE_X_WINDOWS if you want to use the X window system. */
#ifndef HAVE_X_WINDOWS
/* #define HAVE_X_WINDOWS */
#endif
/* Define HAVE_X11 if you want to use version 11 of X windows.
Otherwise, Emacs expects to use version 10. */
#ifndef HAVE_X11
/* #define HAVE_X11 */
#endif
/* Define HAVE_X_MENU if you want to use the X window menu system.
This appears to work on some machines that support X
and not on others. */
#ifndef HAVE_X_MENU
/* #define HAVE_X_MENU */
#endif
/* Define `subprocesses' should be defined if you want to
have code for asynchronous subprocesses
(as used in M-x compile and M-x shell).
@ -78,99 +130,20 @@ and this notice must be preserved on all copies. */
#endif
#endif
/* Define USER_FULL_NAME to return a string
that is the user's full name.
It can assume that the variable `pw'
points to the password file entry for this user.
At some sites, the pw_gecos field contains
the user's full name. If neither this nor any other
field contains the right thing, use pw_name,
giving the user's login name, since that is better than nothing. */
#define USER_FULL_NAME pw->pw_gecos
/* Define AMPERSAND_FULL_NAME if you use the convention
that & in the full name stands for the login id. */
/* #define AMPERSAND_FULL_NAME */
/* Define HIGHPRI as a negative number
if you want Emacs to run at a higher than normal priority.
For this to take effect, you must install Emacs with setuid root.
Emacs will change back to the users's own uid after setting
its priority. */
#ifndef HIGHPRI
/* #define HIGHPRI */
#endif
/* Define LISP_FLOAT_TYPE if you want emacs to support floating-point
numbers. */
#ifndef LISP_FLOAT_TYPE
/* #define LISP_FLOAT_TYPE */
#endif
/* Define GNU_MALLOC if you want to use the *new* GNU memory allocator. */
#ifndef GNU_MALLOC
/* #define GNU_MALLOC */
#endif
/* Define REL_ALLOC if you want to use the relocating allocator for
buffer space. */
#ifndef REL_ALLOC
/* #define REL_ALLOC */
#endif
/* If we're using any sort of window system, define MULTI_SCREEN. */
#ifdef HAVE_X_WINDOWS
#define MULTI_SCREEN
#endif
/* Define LD_SWITCH_SITE to contain any special flags your loader may
need. For instance, if you've defined HAVE_X_WINDOWS above and your
X libraries aren't in a place that your loader can find on its own,
you might want to add "-L/..." or something similar. */
/* #define LD_SWITCH_SITE */
/* Define C_SWITCH_SITE to contain any special flags your compiler may
need. For instance, if you've defined HAVE_X_WINDOWS above and your
X include files aren't in a place that your compiler can find on its
own, you might want to add "-I/..." or something similar. */
/* #define C_SWITCH_SITE */
/* Define this macro if you want to use 16-bit GLYPHs. Currently this
option isn't terribly useful (the current distribution doesn't
support large characters in buffer text), so the configuration
script doesn't provide an option to select it.
A character is displayed on a given terminal by means of a sequence
of one or more GLYPHs. A GLYPH is something that takes up exactly
one display position on the screen.
Emacs can use 8-bit or 16-bit values to represent GLYPHs. Under X
windows, 16-bit GLYPHs allow you to display characters from fonts
too large to be indexed by 8 bits alone, but drawing with 16-bit GLYPHs
is usually quite a bit slower than drawing with 8-bit GLYPHs. */
/* #define GLYPH_16_BIT */
#ifdef GLYPH_16_BIT
#define GLYPH unsigned short
#else
#define GLYPH unsigned char
#endif
/* Define the return type of signal handlers if the s-xxx file
did not already do so. */
#ifndef SIGTYPE
#ifdef __STDC__
#define SIGTYPE void
#else
#define SIGTYPE int
#endif
#endif

View file

@ -55,8 +55,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#undef SIGIO
#endif
#undef NULL
#include "termchar.h"
#include "termopts.h"
#include "cm.h"
@ -183,7 +181,7 @@ DEFUN ("redraw-screen", Fredraw_screen, Sredraw_screen, 1, 1, 0,
{
SCREEN_PTR s;
CHECK_SCREEN (screen, 0);
CHECK_LIVE_SCREEN (screen, 0);
s = XSCREEN (screen);
update_begin (s);
/* set_terminal_modes (); */
@ -998,7 +996,8 @@ update_screen (s, force, inhibit_hairy_id)
if (!line_ins_del_ok)
inhibit_hairy_id = 1;
/* Don't compute for i/d line if just want cursor motion. */
/* See if any of the desired lines are enabled; don't compute for
i/d line if just want cursor motion. */
for (i = 0; i < SCREEN_HEIGHT (s); i++)
if (desired_screen->enable[i])
break;
@ -1211,75 +1210,41 @@ buffer_posn_from_coords (window, col, line)
int window_left = XFASTINT (window->left);
/* The actual width of the window is window->width less one for the
\ which ends wrapped lines, and less one if it's not the
rightmost window. */
DISP_CONTINUE_GLYPH, and less one if it's not the rightmost
window. */
int window_width = (XFASTINT (window->width) - 1
- (XFASTINT (window->width) + window_left
!= SCREEN_WIDTH (XSCREEN (window->screen))));
/* The screen's list of buffer positions of line starts. */
int *bufp = SCREEN_CURRENT_GLYPHS (XSCREEN (window->screen))->bufp;
int startp = marker_position (window->start);
/* Since compute_motion will only operate on the current buffer,
we need to save the old one and restore it when we're done. */
struct buffer *old_current_buffer = current_buffer;
int posn;
struct position *posn;
current_buffer = XBUFFER (window->buffer);
{
/* compute_motion will find the buffer position corresponding to a
screen position, given a buffer position to start at and its
screen position, by scanning from the start to the goal. In
order to make this faster, we need to choose a starting buffer
position with a known screen position as close to the goal as
possible.
The bufp array in the screen_glyphs structure gives the buffer
position of the first character on each screen line. This
would be a perfect starting location, except that there's no
way to know if this character really starts flush with the
beginning of the line or if it is being continued from the
previous line; characters like ?\M-x display as \370 and can
wrap off the end of one line onto the next.
So what we do is start on the target line, and scan upwards
until we find a screen line that starts right after a newline
in the buffer, or at the top of the window; both of these
assure us that the character at bufp starts flush with the
beginning of the line. */
int start_line;
#if 0
/* Unfortunately, the bufp array doesn't seem to be updated properly. */
/* Only works for the leftmost window on a line. bufp is useless
for the others. */
if (window_left == 0)
{
for (start_line = line; start_line > 0; start_line--)
if (FETCH_CHAR (bufp[XFASTINT (window->top) + start_line]-1)
== '\n')
break;
posn = bufp[XFASTINT (window->top) + start_line];
}
else
#endif
{
start_line = 0;
posn = marker_position (window->start);
}
posn
= compute_motion (posn, start_line, window_left,
ZV, line, col - window_left,
window_width, XINT (window->hscroll), 0)
->bufpos;
}
/* It would be nice if we could use SCREEN_CURRENT_GLYPHS (XSCREEN
(window->screen))->bufp to avoid scanning from the very top of
the window, but it isn't maintained correctly, and I'm not even
sure I will keep it. */
posn = compute_motion (startp, 0,
(window == XWINDOW (minibuf_window) && startp == 1
? minibuf_prompt_width : 0),
ZV, line, col - window_left,
window_width, XINT (window->hscroll), 0);
current_buffer = old_current_buffer;
return posn;
/* compute_motion considers screen points past the end of a line
to be *after* the newline, i.e. at the start of the next line.
This is reasonable, but not really what we want. So if the
result is on a line below LINE, back it up one character. */
if (posn->vpos > line)
return posn->bufpos - 1;
else
return posn->bufpos;
}
static int
@ -1625,7 +1590,7 @@ FILE = nil means just close any termscript file currently open.")
if (termscript != 0) fclose (termscript);
termscript = 0;
if (! NULL (file))
if (! NILP (file))
{
file = Fexpand_file_name (file, Qnil);
termscript = fopen (XSTRING (file)->data, "w");
@ -1637,6 +1602,7 @@ FILE = nil means just close any termscript file currently open.")
#ifdef SIGWINCH
SIGTYPE
window_change_signal ()
{
int width, height;
@ -1659,7 +1625,7 @@ window_change_signal ()
{
SCREEN_PTR s = XSCREEN (XCONS (tail)->car);
if (s->output_method == output_termcap)
if (SCREEN_IS_TERMCAP (s))
{
++in_display;
change_screen_size (s, height, width, 0);
@ -1728,10 +1694,8 @@ change_screen_size (screen, newlength, newwidth, pretend)
if (newlength && newlength != SCREEN_HEIGHT (screen))
{
if (XSCREEN (WINDOW_SCREEN (XWINDOW (SCREEN_MINIBUF_WINDOW (screen))))
== screen
&& ! EQ (SCREEN_MINIBUF_WINDOW (screen),
SCREEN_ROOT_WINDOW (screen)))
if (SCREEN_HAS_MINIBUF (screen)
&& ! SCREEN_MINIBUF_ONLY_P (screen))
{
/* Screen has both root and minibuffer. */
set_window_height (SCREEN_ROOT_WINDOW (screen),
@ -1744,7 +1708,7 @@ change_screen_size (screen, newlength, newwidth, pretend)
/* Screen has just one top-level window. */
set_window_height (SCREEN_ROOT_WINDOW (screen), newlength, 0);
if (SCREEN_IS_TERMCAP (screen) == output_termcap && !pretend)
if (SCREEN_IS_TERMCAP (screen) && !pretend)
ScreenRows = newlength;
#if 0
@ -1760,8 +1724,7 @@ change_screen_size (screen, newlength, newwidth, pretend)
if (newwidth && newwidth != SCREEN_WIDTH (screen))
{
set_window_width (SCREEN_ROOT_WINDOW (screen), newwidth, 0);
if (XSCREEN (WINDOW_SCREEN (XWINDOW (SCREEN_MINIBUF_WINDOW (screen))))
== screen)
if (SCREEN_HAS_MINIBUF (screen))
set_window_width (SCREEN_MINIBUF_WINDOW (screen), newwidth, 0);
SCREEN_WIDTH (screen) = newwidth;
@ -1809,7 +1772,7 @@ terminate any keyboard macro currently executing.")
(arg)
Lisp_Object arg;
{
if (!NULL (arg))
if (!NILP (arg))
{
ring_bell ();
fflush (stdout);
@ -1851,7 +1814,7 @@ Optional second arg non-nil means ARG is measured in milliseconds.\n\
if (sec <= 0)
return Qnil;
if (!NULL (millisec))
if (!NILP (millisec))
{
#ifndef HAVE_TIMEVAL
error ("millisecond sit-for not supported on %s", SYSTEM_TYPE);
@ -1941,7 +1904,7 @@ Value is t if waited the full time with no input arriving.")
if (sec <= 0)
return Qt;
if (!NULL (millisec))
if (!NILP (millisec))
{
#ifndef HAVE_TIMEVAL
error ("millisecond sleep-for not supported on %s", SYSTEM_TYPE);
@ -2027,7 +1990,7 @@ init_display ()
system. */
#ifdef HAVE_X_WINDOWS
if (!inhibit_window_system && (display_arg || egetenv ("DISPLAY")))
if (!inhibit_window_system && (display_arg || getenv ("DISPLAY")))
{
Vwindow_system = intern ("x");
#ifdef HAVE_X11

View file

@ -509,14 +509,14 @@ typedef unsigned char UCHAR;
#ifdef NULL
#undef NULL
#endif
#define NULL(x) (XFASTINT (x) == XFASTINT (Qnil))
#define NILP(x) (XFASTINT (x) == XFASTINT (Qnil))
/* #define LISTP(x) (XTYPE ((x)) == Lisp_Cons)*/
#define CONSP(x) (XTYPE ((x)) == Lisp_Cons)
#define EQ(x, y) (XFASTINT (x) == XFASTINT (y))
#define CHECK_LIST(x, i) \
{ if ((XTYPE ((x)) != Lisp_Cons) && !NULL (x)) x = wrong_type_argument (Qlistp, (x)); }
{ if ((XTYPE ((x)) != Lisp_Cons) && !NILP (x)) x = wrong_type_argument (Qlistp, (x)); }
#define CHECK_STRING(x, i) \
{ if (XTYPE ((x)) != Lisp_String) x = wrong_type_argument (Qstringp, (x)); }
@ -698,12 +698,12 @@ extern char *stack_bottom;
/* Check quit-flag and quit if it is non-nil. */
#define QUIT \
if (!NULL (Vquit_flag) && NULL (Vinhibit_quit)) \
if (!NILP (Vquit_flag) && NILP (Vinhibit_quit)) \
{ Vquit_flag = Qnil; Fsignal (Qquit, Qnil); }
/* Nonzero if ought to quit now. */
#define QUITP (!NULL (Vquit_flag) && NULL (Vinhibit_quit))
#define QUITP (!NILP (Vquit_flag) && NILP (Vinhibit_quit))
/* 1 if CH is upper case. */
@ -1079,14 +1079,6 @@ extern Lisp_Object Fprocess_status (), Fkill_process ();
/* defined in callproc.c */
extern Lisp_Object Vexec_path, Vexec_directory, Vdata_directory;
#ifdef MAINTAIN_ENVIRONMENT
/* defined in environ.c */
extern int size_of_current_environ ();
extern void get_current_environ ();
/* extern void current_environ (); */
extern Lisp_Object Fgetenv ();
#endif /* MAINTAIN_ENVIRONMENT */
/* defined in doc.c */
extern Lisp_Object Vdoc_file_name;
extern Lisp_Object Fsubstitute_command_keys ();
@ -1110,8 +1102,4 @@ extern void debugger ();
extern char *malloc (), *realloc (), *getenv (), *ctime (), *getwd ();
extern long *xmalloc (), *xrealloc ();
#ifdef MAINTAIN_ENVIRONMENT
extern unsigned char *egetenv ();
#else
#define egetenv getenv
#endif
extern char *egetenv ();