Chinaunix首页 | 论坛 | 博客
  • 博客访问: 350348
  • 博文数量: 60
  • 博客积分: 1570
  • 博客等级: 上尉
  • 技术积分: 620
  • 用 户 组: 普通用户
  • 注册时间: 2009-11-02 23:37
文章分类

全部博文(60)

文章存档

2012年(2)

2010年(2)

2009年(56)

分类: LINUX

2009-12-09 23:22:33

一. 环境表(Environment List)

(这一节用英文原版的吧,主要是下面的图捣鼓了半天都画不出来)

Each program is also passed an environment list. Like the argument list, the environment list is an array of character pointers, with each pointer containing the address of a null-terminated C string. The address of the array of pointers is contained in the global variable environ:

    extern char **environ;

For example, if the environment consisted of five strings, it could look like . Here we explicitly show the null bytes at the end of each string. We'll call environ the environment pointer, the array of pointers the environment list, and the strings they point to the environment strings.

Figure 7.5. Environment consisting of five C character strings


By convention, the environment consists of

name=value

strings, as shown in . Most predefined names are entirely uppercase, but this is only a convention.

二、 C 程序的存储空间布局

    C 程序一般有下面几部分组成:

        正文段(text segment),初始化数据段(Initialized data segment),非初始化数据段(Uninitialized data segment, 通常称为 bss 段,block started by symbol),栈(Stack),堆(Heap)。

存储空间的典型布局:

Figure 7.6. Typical memory arrangement

 

三、获取和设置环境变量的函数

(这一节做的笔记在保存时出了问题,没有保存成功。后来就直接复制粘贴了原文,郁闷~)

ISO C defines a function that we can use to fetch values from the environment, but this standard says that the contents of the environment are implementation defined.

#include 

char *getenv(const char *name);

Returns: pointer to value associated with name, NULL if not found


 

Note that this function returns a pointer to the value of a name=value string. We should always use getenv to fetch a specific value from the environment, instead of accessing environ directly.

Some environment variables are defined by POSIX.1 in the Single UNIX Specification, whereas others are defined only if the XSI extensions are supported. lists the environment variables defined by the Single UNIX Specification and also notes which implementations support the variables. Any environment variable defined by POSIX.1 is marked with •; otherwise, it is an XSI extension. Many additional implementation-dependent environment variables are used in the four implementations described in this book. Note that ISO C doesn't define any environment variables.

Figure 7.7. Environment variables defined in the Single UNIX Specification

Variable

POSIX.1

FreeBSD 5.2.1

Linux 2.4.22

Mac OS X 10.3

Solaris 9

Description

COLUMNS

terminal width

DATEMSK

XSI

 

 

getdate(3) template file pathname

HOME

home directory

LANG

name of locale

LC_ALL

name of locale

LC_COLLATE

name of locale for collation

LC_CTYPE

name of locale for character classification

LC_MESSAGES

name of locale for messages

LC_MONETARY

name of locale for monetary editing

LC_NUMERIC

name of locale for numeric editing

LC_TIME

name of locale for date/time formatting

LINES

terminal height

LOGNAME

login name

MSGVERB

XSI

   

fmtmsg(3) message components to process

NLSPATH

XSI

sequence of templates for message catalogs

PATH

list of path prefixes to search for executable file

PWD

absolute pathname of current working directory

SHELL

name of user's preferred shell

TERM

terminal type

TMPDIR

pathname of directory for creating temporary files

TZ

time zone information


 

In addition to fetching the value of an environment variable, sometimes we may want to set an environment variable. We may want to change the value of an existing variable or add a new variable to the environment. (In the next chapter, we'll see that we can affect the environment of only the current process and any child processes that we invoke. We cannot affect the environment of the parent process, which is often a shell. Nevertheless, it is still useful to be able to modify the environment list.) Unfortunately, not all systems support this capability. shows the functions that are supported by the various standards and implementations.

Figure 7.8. Support for various environment list functions

Function

ISO C

POSIX.1

FreeBSD 5.2.1

Linux 2.4.22

Mac OS X 10.3

Solaris 9

getenv

putenv

 

XSI

setenv

 

 

unsetenv

 

 

clearenv

     

   


 

clearenv is not part of the Single UNIX Specification. It is used to remove all entries from the environment list.

The prototypes for the middle three functions listed in are

  #include 

  int putenv(char *str);

  int setenv(const char *name, const char *value,
 int rewrite);

  int unsetenv(const char *name);

All return: 0 if OK, nonzero on error


 

The operation of these three functions is as follows.

  • The putenv function takes a string of the form name=value and places it in the environment list. If name already exists, its old definition is first removed.

  • The setenv function sets name to value. If name already exists in the environment, then (a) if rewrite is nonzero, the existing definition for name is first removed; (b) if rewrite is 0, an existing definition for name is not removed, name is not set to the new value, and no error occurs.

  • The unsetenv function removes any definition of name. It is not an error if such a definition does not exist.

    Note the difference between putenv and setenv. Whereas setenv must allocate memory to create the name=value string from its arguments, putenv is free to place the string passed to it directly into the environment. Indeed, on Linux and Solaris, the putenv implementation places the address of the string we pass to it directly into the environment list. In this case, it would be an error to pass it a string allocated on the stack, since the memory would be reused after we return from the current function.

It is interesting to examine how these functions must operate when modifying the environment list. Recall : the environment listthe array of pointers to the actual name=value stringsand the environment strings are typically stored at the top of a process's memory space, above the stack. Deleting a string is simple; we simply find the pointer in the environment list and move all subsequent pointers down one. But adding a string or modifying an existing string is more difficult. The space at the top of the stack cannot be expanded, because it is often at the top of the address space of the process and so can't expand upward; it can't be expanded downward, because all the stack frames below it can't be moved.

  1. If we're modifying an existing name:

    1. If the size of the new value is less than or equal to the size of the existing value, we can just copy the new string over the old string.

    2. If the size of the new value is larger than the old one, however, we must malloc to obtain room for the new string, copy the new string to this area, and then replace the old pointer in the environment list for name with the pointer to this allocated area.

  2. If we're adding a new name, it's more complicated. First, we have to call malloc to allocate room for the name=value string and copy the string to this area.

    1. Then, if it's the first time we've added a new name, we have to call malloc to obtain room for a new list of pointers. We copy the old environment list to this new area and store a pointer to the name=value string at the end of this list of pointers. We also store a null pointer at the end of this list, of course. Finally, we set environ to point to this new list of pointers. Note from that if the original environment list was contained above the top of the stack, as is common, then we have moved this list of pointers to the heap. But most of the pointers in this list still point to name=value strings above the top of the stack.

    2. If this isn't the first time we've added new strings to the environment list, then we know that we've already allocated room for the list on the heap, so we just call realloc to allocate room for one more pointer. The pointer to the new name=value string is stored at the end of the list (on top of the previous null pointer), followed by a null pointer.

     

阅读(2081) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~