且欲近寻彭泽宰,陶然共醉菊花怀。
系统调用 uname()
用于获取有关当前操作系统内核的名称和信息,函数原型如下所示(可通过"man 2 uname
"命令查看):
#include
int uname(struct utsname *buf);
使用该函数需要包含头文件
。
函数参数和返回值含义如下:
buf
:struct utsname
结构体类型指针,指向一个struct utsname
结构体类型对象。
返回值:成功返回 0;失败将返回-1,并设置errno
。
uname()
函数用法非常简单,先定义一个 struct utsname
结构体变量,调用 uname()
函数时传入变量的地址即可,struct utsname
结构体如下所示:
struct utsname {
char sysname[]; /* 当前操作系统的名称 */
char nodename[]; /* 网络上的名称(主机名) */
char release[]; /* 操作系统内核版本 */
char version[]; /* 操作系统发行版本 */
char machine[]; /* 硬件架构类型 */
#ifdef _GNU_SOURCE
char domainname[];/* 当前域名 */
#endif
};
可以看到,struct utsname
结构体中的所有成员变量都是字符数组,所以获取到的信息都是字符串。
测试:
编写一个简单地程序,获取并打印出当前操作系统名称、主机名、内核版本、操作系统发行版本以及处理器硬件架构类型等信息,测试代码如下:
#include
#include
#include
int main(void)
{
struct utsname os_info;
int ret;
/* 获取信息 */
ret = uname(&os_info);
if (-1 == ret) {
perror("uname error");
exit(-1);
}
/* 打印信息 */
printf("操作系统名称: %s\n", os_info.sysname);
printf("主机名: %s\n", os_info.nodename);
printf("内核版本: %s\n", os_info.release);
printf("发行版本: %s\n", os_info.version);
printf("硬件架构: %s\n", os_info.machine);
exit(0);
}
运行结果:
sundp@sundongpeng:~/workspace/c_program/April$ gcc uname.c
sundp@sundongpeng:~/workspace/c_program/April$ ./a.out
操作系统名称: Linux
主机名: sundongpeng
内核版本: 4.15.0-29-generic
发行版本: #31~16.04.1-Ubuntu SMP Wed Jul 18 08:54:04 UTC 2018
硬件架构: x86_64
sysinfo
系统调用可用于获取一些系统统计信息,其函数原型如下所示:
#include
int sysinfo(struct sysinfo *info);
函数参数和返回值含义如下:
info
:struct sysinfo
结构体类型指针,指向一个struct sysinfo
结构体类型对象。
返回值:成功返回 0;失败将返回-1,并设置errno
。
同样 sysinfo()
函数用法也非常简单,先定义一个 struct sysinfo
结构体变量,调用 sysinfo()
函数时传入变量的地址即可,struct sysinfo
结构体如下所示:
struct sysinfo {
long uptime; /* 自系统启动之后所经过的时间(以秒为单位) */
unsigned long loads[3]; /* 1, 5, and 15 minute load averages */
unsigned long totalram; /* 总的可用内存大小 */
unsigned long freeram; /* 还未被使用的内存大小 */
unsigned long sharedram; /* Amount of shared memory */
unsigned long bufferram; /* Memory used by buffers */
unsigned long totalswap; /* Total swap space size */
unsigned long freeswap; /* swap space still available */
unsigned short procs; /* 系统当前进程数量 */
unsigned long totalhigh; /* Total high memory size */
unsigned long freehigh; /* Available high memory size */
unsigned int mem_unit; /* 内存单元大小(以字节为单位) */
char _f[20-2*sizeof(long)-sizeof(int)]; /* Padding to 64 bytes */
};
测试:
#include
#include
#include
int main(void)
{
struct sysinfo sys_info;
int ret;
/* 获取信息 */
ret = sysinfo(&sys_info);
if (-1 == ret) {
perror("sysinfo error");
exit(-1);
}
/* 打印信息 */
printf("uptime: %ld\n", sys_info.uptime);
printf("totalram: %lu\n", sys_info.totalram);
printf("freeram: %lu\n", sys_info.freeram);
printf("procs: %u\n", sys_info.procs);
exit(0);
}
运行结果:
sundp@sundongpeng:~/workspace/c_program/April$ gcc sysinfo.c
sundp@sundongpeng:~/workspace/c_program/April$ ./a.out
操作系统名称: Linux
主机名: sundongpeng
内核版本: 4.15.0-29-generic
发行版本: #31~16.04.1-Ubuntu SMP Wed Jul 18 08:54:04 UTC 2018
硬件架构: x86_64
此函数可用于单独获取 Linux
系统主机名,与 struct utsname
数据结构体中的 nodename
变量一样,gethostname
函数原型如下所示(可通过"man 2 gethostname
"命令查看):
#include
int gethostname(char *name, size_t len);
使用此函数需要包含头文件
。
函数参数和返回值含义如下:
name
:指向用于存放主机名字符串的缓冲区。
len
:缓冲区长度。
返回值:成功返回0
,;失败将返回-1
,并会设置errno
。
测试:
使用 gethostname
函数获取系统主机名:
#include
#include
#include
#include
int main(void)
{
char hostname[20];
int ret;
memset(hostname, 0x0, sizeof(hostname));
ret = gethostname(hostname, sizeof(hostname));
if (-1 == ret) {
perror("gethostname error");
exit(ret);
}
puts(hostname);
exit(0);
}
运行结果:
sundp@sundongpeng:~/workspace/c_program/April$ gcc gethostname.c
sundp@sundongpeng:~/workspace/c_program/April$ ./a.out
sundongpeng
sysconf()
函数是一个库函数,可在运行时获取系统的一些配置信息,譬如页大小(page size
)、主机名的最大长度、进程可以打开的最大文件数、每个用户 ID
的最大并发进程数等。其函数原型如下所示:
#include
long sysconf(int name);
使用该函数需要包含头文件
。
调用 sysconf()
函数获取系统的配置信息,参数 name
指定了要获取哪个配置信息,参数 name
可取以下任何一个值(都是宏定义,可通过 man 手册查询):
⚫ _SC_ARG_MAX:exec 族函数的参数的最大长度,exec 族函数后面会介绍,这里先不管!
⚫ _SC_CHILD_MAX:每个用户的最大并发进程数,也就是同一个用户可以同时运行的最大进程数。
⚫ _SC_HOST_NAME_MAX:主机名的最大长度。
⚫ _SC_LOGIN_NAME_MAX:登录名的最大长度。
⚫ _SC_CLK_TCK:每秒时钟滴答数,也就是系统节拍率。
⚫ _SC_OPEN_MAX:一个进程可以打开的最大文件数。
⚫ _SC_PAGESIZE:系统页大小(page size)。
⚫ _SC_TTY_NAME_MAX:终端设备名称的最大长度。
⚫ ……
除以上之外,还有很多,这里就不再一一列举了,可以通过 man
手册进行查看,用的比较多的是_SC_PAGESIZE
和_SC_CLK_TCK
,若指定的参数 name
为无效值,则 sysconf()
函数返回-1,并会将 errno
设置为 EINVAL
。否则返回的值
便是对应的配置值。注意,返回值是一个 long
类型的数据。
使用示例
获取每个用户的最大并发进程数、系统节拍率和系统页大小。
#include
#include
#include
int main(void)
{
printf("每个用户的最大并发进程数: %ld\n", sysconf(_SC_CHILD_MAX));
printf("系统节拍率: %ld\n", sysconf(_SC_CLK_TCK));
printf("系统页大小: %ld\n", sysconf(_SC_PAGESIZE));
exit(0);
}
运行结果:
sundp@sundongpeng:~/workspace/c_program/April$ gcc sysconf.c
sundp@sundongpeng:~/workspace/c_program/April$ ./a.out
每个用户的最大并发进程数: 31581
系统节拍率: 100
系统页大小: 4096