linux c programming: process environment

A process terminated:

A process can register several functions (check it out for yourself), these functions are automatically called by exit, these functions are called termination functions, and the atexit function can register these functions. The order in which exit calls the termination handler is opposite to the order in which atexit is registered. If a function is registered multiple times, it will also be called multiple times.

The program is abnormally or terminated normally when the following functions are called:

There are 8 ways to terminate a process, the first 5 are normal termination, and the last three are abnormal termination:
1 Return from the main function;
2 Call the exit function;
3 Call _exit or _Exit;
4 The last The thread returns from the startup routine;
5 the last thread calls pthread_exit;
6 calls the abort function;
7 receives a signal and terminates;

8 The last thread responded to the cancel request.

 The essential difference between exit() and _exit() and _Exit() functions is whether to enter the kernel immediately. Both _exit() and _Exit() functions enter the kernel immediately after being called, without performing some cleanup processing, but exit() will perform some cleanup processing, which is why there is an atexit() function, because the exit() function needs to perform cleanup processing and a series of operations. These termination processing functions are actually to complete various so-called The actual body of the cleanup operation.

Let's verify the execution order of atexit:

#include <stdio.h>

#include <stdlib.h>

void func1(){

printf("func1");

}

void func2(){

printf("func2");

}

void func3(){

printf("func3");

}

int main(){

atexit(func1);

atexit(func2);

atexit(func3);

return 1;

}

Execution result: It can be seen that the calling order and registration order of the atexit function are reversed

func3

func2

func1

 

Two command line parameters and environment table

When executing a program, command line parameters can be passed to the program by passing the argc and argv parameters in the main function

int main(int argc,char *argv[]){

for(int j=0;j<argc;j++){

printf("argc[%d]:%s\n",j,argv[j]);

}

}

Results of the. The first parameter is the specific command line.

root@zhf-maple:/home/zhf/c_prj# ./chapter7 arg1 arg2 arg3

argc[0]:./chapter7

argc[1]:arg1

argc[2]:arg2

argc[3]:arg3

 

Environment table:

Each program receives an environment table. Like the parameter table, the environment table is an array of character pointers, where each pointer contains the address of a null-terminated C string. The global variable environ contains the address of the pointer array

The calling method is as follows:

extern char **environ;

int main(int argc,char *argv[]){

for(int i=0;environ[i]!=NULL;i++){

printf("%s\n",environ[i]);

}

return 1;

}

But in the UNIX system, the main function actually takes 3 parameters, the third parameter is the address of the environment table

int main(int argc,char *argv[],char *envp[]){

for(int i=0;envp[i]!=NULL;i++){

printf("%s\n",envp[i]);

}

return 1;

}

 

If you want to query or set a single environment variable how to operate, you need to use several functions that manipulate environment variables:

char *getenv(const char *name);  

The return value of the function is the address of the value string in name=value, or NULL if not found.

int putenv(char *str);  

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

int unsetenv(const char *name);  

The operation of putenv is to put the name=value string into the environment table. If the name exists, its original definition will be deleted first.
 setenv sets name to value. If name exists in the environment, when rewrite is non-zero, its existing definition is deleted first. When rewrite is 0, its existing definition is not deleted (name is not set to a new value, and no error occurs);
unsetenv deletes the definition of name. No error even if name does not exist.

Let's see how to use it:

Get the address of HOME by setting name="HOME"

void getenv_function(){

char * ret;

const char *name="HOME";

ret=getenv(name);

printf("%s",ret);

}

Set environment variables

char str[10]="sex=male";

void putenv_function(){

putenv(str);

}

setenv set environment variables

void setenv_function(){

char name[10]="name";

char *str=(char *)malloc(20*sizeof(char));

const char *value="zhf";

memcpy(str,name,sizeof(name));

setenv(str,value,1);

}

The difference between putenv and setenv:

 setenv must allocate storage to create name=value strings from its arguments. At the same time, putenv does not need to put the argument string passed to it directly into the environment.
Note: When using putenv, an error occurs when passing a string stored on the stack as an argument to the function, because the memory area occupied by its stack frame may be reused when returning from the current function.

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325115720&siteId=291194637