uc_01_Computer system layering_environment variables_error handling

1. Computer system layering

1. What is an operating system?

The operating system is a system software that manages computer hardware and software resources, referred to as OS.

2. Computer system layering:

The operating system manages the computer’s hardware resources through drivers.

The operating system interacts with the user through system calls.

The operating system hierarchy is as shown below:

2. Environment variables

1. What are environment variables?

Personal summary: bashrc manages permanent global environment variables, and the bash terminal manages temporary global and temporary local environment variables.

When a program starts executing, the kernel allocates environment variables to the process. When execution ends, the kernel releases the environment variables.

Each executing program has its own environment variables.

The shell (Bash for Ubuntu) uses a feature called environment variables to store information about the working environment.

Processes can access the computer’s resources through environment variables.

Enter the env command in the terminal to view the bash global environment variable list. (At the same time, global environment variables can be inherited by child processes, but local environment variables cannot be inherited by child processes)

You can view the value of an environment variable through echo $name.

2. Add/delete environment variables

Enter the key=value format in the terminal window, press Enter, and add the local/custom environment variables of this bash process (remember not to add spaces).

For example, FOOD=guobaorou means that in the current bash, add a local environment variable named FOOD with a value of guobaorou for this bash process (if the environment variable FOOD exists, change its value), which cannot be viewed through env at this time.

Local environment variables can be upgraded to global environment variables through the export name (such as export FOOD) command. At this time, the FOOD environment variable can be viewed through the env command.

The environment variables added in this terminal window will disappear after the window is closed (that is, the bash process ends this time). When a new terminal window is opened, the env command cannot view the FOOD environment variable. This needs to be added to the bashrc file in the user’s home directory.

Enter unset name in the terminal window and press Enter to delete the environment variable.

Changed environment variables in bashrc must be managed in bashrc for the effect to be permanent.

3. Commonly used environment variables PATH

The value of the PATH environment variable is the search path s of the bash process for commands.

Enter echo $PATH in the terminal and press Enter to get the value of PATH (a bunch of paths separated by colons) as follows:

/opt/Qt5.12.8/5.12.8/gcc_64/bin:/opt/Qt5.12.8/Tools/QtCreator/bin:/home/tarena/bin:/home/tarena/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games< strong>:/usr/local/games:/snap/bin

You can enter PATH=$PATH:. in the terminal to add the current directory . to this bash. Enter run.sh directly to execute it without having to enter ./run.sh. This method becomes invalid after closing the terminal window.

You can add PATH=$PATH:. (do not add spaces or semicolons) in the last line of the .bashrc file to effectively add the directory . to the PATH environment variable in the long term. middle.

There is a .bashrc script file in the home directory. The contents of the script file will be executed every time before the bash process is started. If you want the environment variable settings to be effective for each bash process, you need to write the environment variable settings in the script file.

Executing the source ~/.bashrc command will make the file immediately effective for the current bash without restarting the bash terminal.

4. Commonly used environment variables PS1

This environment variable determines the content of the window command line prompt.

Use the echo $PS1 command to view the value of this environment variable.

The settings and effects on PS1 at the end of my .bashrc file:

 export PS1="\[\e[35;1m\]\W$\[\e[0m\]"

Changing 32 to 35 is green.

Reference PS1 settings in Linux: PS1 settings in Linux-comcn2-ChinaUnix Blog

3. Environment variable table

1. Theory

Each process has an independent environment variable table, and each entry in it is an environment variable in the form of “key=value”:

The environment variable table is an array of character pointers terminated by a NULL pointer. Each element in the character pointer array is a character pointer pointing to a null-terminated string, which is an environment variable in the form of “key=value”.

The address of the character pointer array in the environment variable table is stored in the global variable pointer environ:

2. Method 1: Access all environment variables through the global environment variable pointer environ:

extern char** environ;

char**pp;

for(pp = environ; *pp; pp + + ){

printf(“%s\
, *pp);

}

3. Method 2: Access all environment variables of the process through the third parameter envp[] (the starting address of the environment variable table) of the main function:

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

char**pp;

for(pp = envp; *pp; pp + + ){

printf(“%s\
“, *pp);

}

return 0;

}

//environ.c environment variable table
#include<stdio.h>

int main(int argc,char* argv[],char* envp[]){
    
    extern char** environ; //Method 1, the first address of the character pointer array environ
    /*for(char** pp = environ;*pp;pp + + ){
        printf("%s\
",*pp);
    }*/
    
    for(char** pp = envp;*pp;pp + + ){ //Method 2, the third parameter envp[] of the main function
        printf("%s\
",*pp);
    }
    
    printf("environ = %p\
",environ); //Verify that the two methods get the same address
    printf("envp = %p\
",envp);
    return 0;
}

4. Error handling

The operating environment, human operations, etc. will cause errors during program execution. What if you obtain the cause of the error?

1. Pass the error number errno

The system stores the error number of the most recent erroneous system call (not necessarily the most recent system call) in the defined integer type global variable errno.

Through the error number, you can know the cause of the error

The header file /usr/include/errno.h contains an external declaration of the errno global variable

The header file /usr/include/asm-generic/errno-bash.h contains macro definitions for various error numbers

2. Through strerror() function

#include

char* strerror(int errnum)

Function: Convert the error number errno in the form of an integer into a meaningful string

Parameter: errnum error number

Return value: Returns the description string corresponding to the errnum error number.

3. Through the perror() function

#include

void perror(char const* tag)

Function: Print the error message of the latest function call on the standard error device stdout

Parameter: tag is the prompt content defined by the user. When outputting, it will be automatically added between the prompt content and the error message.

Colon: split.

//error.c error handling
#include<stdio.h>
#include<stdlib.h>// malloc() free()
#include<errno.h>// errno
#include<string.h>// strerror()

int main(void){
    int* p = malloc(0xffffffffffffffff);
    if(p==NULL){

        //malloc failed --> reason --> number --> errno
        printf("errno = %d\
",errno); //Method 1
        printf("malloc:%s\
",strerror(errno)); //Method 2, depends on method 1

        perror("malloc"); //Method 3

        return -1;
    }
    free(p);
    p = NULL;
    return 0;
}

4. Pay attention to error handling through errno

Although all error numbers are not zero, because the global variable errno that stores the error number is not cleared when the function is executed successfully, whether the value of this variable is zero cannot be used to determine whether the latest function call was successful. judgment conditions.

The correct approach is to first determine whether an error occurred based on the return value of the function. After determining that an error occurred, then determine what specific error occurred based on the value of errno.