Linux系统信息类系统调用总结与示例

 
Category: Linux-Shell

进程基本信息

环境变量: getenv与environ

下面代码列出了三种获取全部环境变量的方法:

#include <stdio.h>
#include <stdlib.h>

void t1() {
    printf("LANG=%s\n", getenv("LANG"));
    printf("PWD=%s\n", getenv("PWD"));
    printf("SHELL=%s\n", getenv("SHELL"));
}

extern char** environ;
void t2() {
    int i = 0;
    while (environ[i] != NULL) printf("environ[%d]=%s\n", i, environ[i]), ++i;
}
/* environ[0]=SHELL=/bin/bash */

int main(int argc, char* argv[], char* envp[]) {
    /* t1(); */
    t2();
    /* for (int i = 0; envp[i] != NULL; ++i) */
    /*     printf("envp[%d]=%s\n", i, envp[i]); */
    return 0;
}
  1. getenv函数, 需要制定参数, 给出值.
  2. environ全局变量, 直接遍历此二维字符数组指针, 即可得到信息.
  3. 直接传入main的第三个参数char* envp[], 与2一样, 遍历即可.

当然, 通过Shell程序printenv可以一次性获取全部键值对:

$ printenv | cat -n # 加上行号
1	SHELL=/bin/bash
2	NVM_INC=/home/zorch/.nvm/versions/node/v16.18.1/include/node
3	CONDA_EXE=/home/zorch/miniforge3/bin/conda

进程/(有效)用户/(有效)组ID

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
    printf("pid=%d\n", getpid());
    printf("ppid=%d\n", getppid());
    printf("uid=%d\n", getuid());
    printf("euid=%d\n", geteuid());
    printf("gid=%d\n", getgid());
    printf("egid=%d\n", getegid());
    return 0;
}
/* pid=57663 */
/* ppid=57658 */
/* uid=1001 */
/* euid=1001 */
/* gid=1001 */
/* egid=1001 */

库/系统信息

glibc库版本

#include <stdio.h>
#include <stdlib.h>
#include <gnu/libc-version.h> // gnu_get_libc_version

int main(int argc, char *argv[]) {
    printf("glibc version=%s\n", gnu_get_libc_version());
    // clang
    /* glibc version=2.31 */
    // gcc
    /* glibc version=2.35 */
    printf("glibc version=%d.%d\n", __GLIBC__, __GLIBC_MINOR__);
    return 0;
}

系统信息: uname

man 2 uname

#include <stdio.h>
#include <stdlib.h>
#include <sys/utsname.h>

int main(int argc, char *argv[]) {
    struct utsname uts;
    if (uname(&uts) == -1) fprintf(stderr, "uname"), exit(1);

    printf("Node name:   %s\n", uts.nodename);
    printf("System name: %s\n", uts.sysname);
    printf("Release:     %s\n", uts.release);
    printf("Version:     %s\n", uts.version);
    printf("Machine:     %s\n", uts.machine);
#ifdef _GNU_SOURCE
    printf("Domain name: %s\n", uts.domainname);
#endif
    exit(EXIT_SUCCESS);
    return 0;
}
/* Node name:   xxx */
/* System name: Linux */
/* Release:     5.4.0-135-generic */
/* Version:     #152-Ubuntu SMP Wed Nov 23 20:19:22 UTC 2022 */
/* Machine:     x86_64 */

系统限制

运行时获取系统限制:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>

static void /* Print 'msg' plus sysconf() value for 'name' */
sysconfPrint(const char *msg, int name) {
    long lim;

    errno = 0;
    lim = sysconf(name);
    if (lim != -1) { /* Call succeeded, limit determinate */
        printf("%s %ld\n", msg, lim);
    } else {
        if (errno == 0) /* Call succeeded, limit indeterminate */
            printf("%s (indeterminate)\n", msg);
        else /* Call failed */
            /* errExit("sysconf %s", msg); */
            fprintf(stderr, "error \n");
    }
}

extern char *program_invocation_name;
extern char *program_invocation_short_name;
int main(int argc, char *argv[]) {
    sysconfPrint("_SC_ARG_MAX:        ", _SC_ARG_MAX);
    sysconfPrint("_SC_LOGIN_NAME_MAX: ", _SC_LOGIN_NAME_MAX);
    sysconfPrint("_SC_OPEN_MAX:       ", _SC_OPEN_MAX);
    sysconfPrint("_SC_NGROUPS_MAX:    ", _SC_NGROUPS_MAX);
    sysconfPrint("_SC_PAGESIZE:       ", _SC_PAGESIZE);
    sysconfPrint("_SC_RTSIG_MAX:      ", _SC_RTSIG_MAX);
    printf("absolute path=%s\n", program_invocation_name);
    printf("relative path=%s\n", program_invocation_short_name);
    exit(EXIT_SUCCESS);
}
/* _SC_ARG_MAX:         2097152 */
/* _SC_LOGIN_NAME_MAX:  256 */
/* _SC_OPEN_MAX:        65535 */
/* _SC_NGROUPS_MAX:     65536 */
/* _SC_PAGESIZE:        4096 */
/* _SC_RTSIG_MAX:       32 */
/* absolute path=./sysconf-1.out */
/* relative path=sysconf-1.out */

运行时获取与文件/路径相关的限制:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>

static void /* Print 'msg' plus value of fpathconf(fd, name) */
fpathconfPrint(const char *msg, int fd, int name) {
    long lim;

    errno = 0;
    lim = fpathconf(fd, name);
    if (lim != -1) { /* Call succeeded, limit determinate */
        printf("%s %ld\n", msg, lim);
    } else {
        if (errno == 0) /* Call succeeded, limit indeterminate */
            printf("%s (indeterminate)\n", msg);
        else /* Call failed */
            /* errExit("fpathconf %s", msg); */
            fprintf(stderr, "error");
    }
}

int main(int argc, char *argv[]) {
    fpathconfPrint("_PC_NAME_MAX: ", STDIN_FILENO, _PC_NAME_MAX);
    fpathconfPrint("_PC_PATH_MAX: ", STDIN_FILENO, _PC_PATH_MAX);
    fpathconfPrint("_PC_PIPE_BUF: ", STDIN_FILENO, _PC_PIPE_BUF);
    exit(EXIT_SUCCESS);
}
/* _PC_NAME_MAX:  255 */
/* _PC_PATH_MAX:  4096 */
/* _PC_PIPE_BUF:  4096 */