Changing Solaris environment variables so os:getenv/1 gets the ne w value

Ulf Wiger <>
Fri Mar 24 15:59:51 CET 2000


Sean,

Here's a little linked-in driver we use to change environment
variables in a running system:

This particular driver only cares about the TZ env var, and we use it
to manage timezones in AXD301 (we let Solaris run in UTC time, and
allow the operator to specify timezone/daylight savings parameters for
Erlang). I'm sure you can modify it to set the DISPLAY variable
instead. But if you only want to do it for appmon, you might want to
consider running appmon on another node and connecting the nodes via
distributed Erlang. Using the job control (Ctrl-G), you can also run a
remote shell from this other node.


The Erlang code associated with the driver looks like this:

handle_call(initial_start, From, State) ->
    case code:priv_dir(sys1) of
        {error, _} -> % Will happen when running block test
            {reply, nok, []};
        Path ->
            {Dir, _FileName} =
                sysI:find_file(filename:join(Path, "bin"),
			       "sysTimezone.so"),
            erl_ddll:load_driver(Dir,  "sysTimezone"),
            Port = open_port({spawn, sysTimezone}, [binary,
						    {packet,2}]),
            [Obj] = mnesia:dirty_read({sys_timezone,
				      ?SYS_TIMEZONE_INDEX}),     
            send_to_driver(Port, Obj#sys_timezone.sysTZstring),
            {reply, ok, [Port]}
    end;

handle_call({update, Tz}, From, [Port]) ->
    send_to_driver(Port, Tz),
    {reply, ok, [Port]};

send_to_driver(Port, Tz) ->
    Port ! {self(), {command, Tz}}.


/Uffe

On Fri, 24 Mar 2000, Sean Hinde wrote:

SH>Hi all,
SH>
SH>Something which has been perplexing me for a while.
SH>
SH>When running an embedded system, I want to be able to change the DISPLAY
SH>environment variable so that a call to to_erl can start appmon displayed on
SH>a remote host.
SH>
SH>If I simply do
SH>export DISPLAY=host:0.0 
SH>to_erl
SH>Attaching to /tmp/erlang.pipe.2 (^D to exit)
SH>
SH>()2> os:getenv("DISPLAY").
SH>false
SH>
SH>
SH>I know I can set DISPLAY in the start script, but I don't want to have to
SH>restart the node to change the DISPLAY variable!
SH>
SH>Has anyone come up with a solution to this in the past?
SH>
SH>Thanks,
SH>
SH>Sean
SH>

-- 
Ulf Wiger, Chief Designer AXD 301         <>
Ericsson Telecom AB                          tfn: +46  8 719 81 95
Varuvägen 9, Älvsjö                          mob: +46 70 519 81 95
S-126 25 Stockholm, Sweden                   fax: +46  8 719 43 44
-------------- next part --------------
/* -----------------------------------------------------------------
 * %CCaseFile:	sysTimezone.c %
 * %CCaseRev:	/main/Inc4/2 %
 * %CCaseDate:	97-11-26 %
 * %CCaseDocNo:	66/190 55-CNA 121 70 %
 * Author:      Tomas Pihl <>
 *
 * Short description:
 *
 * This is a linked-in driver which sets the timezone for the
 *  beam-process based on what an operator defines.
 *
 * ------------------------------------------------------------------
 * Rev      Date       Name        What
 * -----    -------    --------    --------------------------
 * PA1      971125     etxtopi     First try.
 * ------------------------------------------------------------------
 */

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "driver.h"

static struct driver_entry my_driver_entry;

static long sysTimezone_start(long, char*);
static char* tz_string = 0;

long
sysTimezone_start(long port, char* buf)
{
#ifdef DEBUG
     fprintf(stderr, "sysTimezone.so loaded...\n");
#endif

     return (long) port;
}

int sysTimezone_stop() {}
int sysTimezone_null_func() {}

/*
 * output() - This is the main function. buf contains the TZ-string we 
 * should use to set the timezone with.
 */
int
sysTimezone_output(long port, char* buf, int count)
{
     /* free tz_string if it has been malloced once already */
     if (tz_string != 0)
	  free(tz_string);
	       
     tz_string = (char*) malloc(count+1);
     
     memcpy(tz_string, buf, count);
     tz_string[count] = '\0';

#ifdef DEBUG
     fprintf(stderr, "sysTimezone.so: Setting timezone to [%s]\n",tz_string);
#endif
     /* eg. "TZ=AXD301-1AXD-2,116/2:00:00,265/2:00:00" */     
     putenv(tz_string);

     return 0;
}

/*
 * Initialize and return a driver entry struct
 */
struct driver_entry*
driver_init(void *handle)
{
     my_driver_entry.init = sysTimezone_null_func;     /* Not used */
     my_driver_entry.start = sysTimezone_start;
     my_driver_entry.stop = sysTimezone_stop;
     my_driver_entry.output = sysTimezone_output;
     my_driver_entry.ready_input = sysTimezone_null_func;
     my_driver_entry.ready_output = sysTimezone_null_func;
     my_driver_entry.driver_name = "sysTimezone";
     my_driver_entry.finish = sysTimezone_null_func;
     my_driver_entry.handle = handle;  /* MUST set this!!! */
     
     return &my_driver_entry;
}


More information about the erlang-questions mailing list