From owner-freebsd-bugs Mon May 15 11:00:38 1995 Return-Path: bugs-owner Received: (from majordom@localhost) by freefall.cdrom.com (8.6.10/8.6.6) id LAA09217 for bugs-outgoing; Mon, 15 May 1995 11:00:38 -0700 Received: from cs.weber.edu (cs.weber.edu [137.190.16.16]) by freefall.cdrom.com (8.6.10/8.6.6) with SMTP id LAA09211 for ; Mon, 15 May 1995 11:00:37 -0700 Received: by cs.weber.edu (4.1/SMI-4.1.1) id AA10052; Mon, 15 May 95 11:53:43 MDT From: terry@cs.weber.edu (Terry Lambert) Message-Id: <9505151753.AA10052@cs.weber.edu> Subject: Re: login.c environ=envinit ? To: bde@zeta.org.au (Bruce Evans) Date: Mon, 15 May 95 11:53:43 MDT Cc: freebsd-bugs@FreeBSD.org, henrich@crh.cl.msu.edu In-Reply-To: <199505140525.PAA15514@godzilla.zeta.org.au> from "Bruce Evans" at May 14, 95 03:25:12 pm X-Mailer: ELM [version 2.4dev PL52] Sender: bugs-owner@FreeBSD.org Precedence: bulk > >Im looking at login.c ~line 400 where we reset the user environment if the p > >flag is passed, and we do this but just re-assigning the environment global. > >Shouldnt we free the environment memory before doing that? > > Only if the environment memory was malloced. But there is no way for login > to know. Only setenv() knows. Perhaps unsetenv((char *)0) should be a > standard way of unsetting everything. unsetenv() currently doesn't even > know if setenv() called malloc and doesn't free anything. Perhaps the environment should be seperately allocated off the proc struct instead of being in the users address space at all. Perhaps a multiplex system call with a sub command code should be used to manipulate it. #define ENV_GET 0x00 /* get one variable*/ #define ENV_PUT 0x01 /* set one variable*/ #define ENV_GET_ALL 0x02 /* retrieve for user execle*/ Perhaps this system call should have a designator code with it. #define ENV_CURPROC 0x00 /* current processes environment*/ /* all other values are PID*/ Perhaps it's prototype ought to look like: int environment( int command, pid_t pid, caddr_t arg); Perhaps "arg" ought to be a large buffer for "ENV_GET_ALL", but for "ENV_GET" and "ENV_PUT" ought to be "env_gp_t" and that ought to be defined as: typedef struct env_gp_str { char *name; char *val; } env_gp_t; Perhaps getenv() should be rewritten as: char * getenv( const char *name) { env_gp_t env_gp; static char rbuf[ MAXENVVARSIZ]; env_gp.name = name; env_gp.val = rbuf; if( environment( ENV_GET, ENV_CURPROC, &env_gp)) return( NULL); return( rbuf); } Perhaps putenv() should be rewritten as: int putenv( const char *string) { env_gp_t env_gp; /* * Whether we 0 the equals or copy to set the name field * depends on whether you want to allow string to be writeable. * Ideally, you change the syntax of putenv to take two * arguments. Less ideally, you copy to a local stack buffer, * point the name at the start of the string, point the val * after the equals, and change the equals to a 0 locally. */ if( environment( ENV_GET, ENV_CURPROC, &env_gp)) return( -1); return( 0); } Or perhaps not; after all, this would allow you to make variant symbolic links that worked when the environment was changed from the initial environment, would allow you to modify the parent's environment, would let you modify the process group leader's environment (group logical name table?), or the environment of init (system logical name table?) and enforce those semantics in a prioritized fashion across the getent/putenv calls. And who would want those features? Terry Lambert terry@cs.weber.edu --- Any opinions in this posting are my own and not those of my present or previous employers.