uname 命令如何实现?

uname 命令如何实现?unam命令示例代码#include<sys/utsname.h>#include<stdio.h>#include<string.h>#include<stdlib.h>#include<errno.h>intmain(intargc,char*argv[]){structutsnamebuf;if(uname(&buf)<0){perror(“

大家好,欢迎来到IT知识分享网。

strace 跟踪 uname 命令执行

strace 跟踪得到下面这些关键信息:

uname({sysname="Linux", nodename="debian-10", ...}) = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0x1), ...}) = 0
write(1, "Linux debian-10 4.19.0-16-amd64 "..., 87Linux debian-10 4.19.0-16-amd64 #1 SMP Debian 4.19.181-1 (2021-03-19) x86_64 GNU/Linux

关键的过程是调用 uname 系统调用,然后输出获取到的信息。

uname 命令示例代码

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

int main(int argc, char *argv[])
{ 
   
    struct utsname buf;

    if (uname(&buf) < 0) { 
   
        perror("uname failed\n");
        return errno;
    }

    printf("nodename is %s, release is %s, version is %s, machine is %s\n",
            buf.nodename, buf.release, buf.version, buf.machine);

    return 0;
}

运行示例如下:

$ ./uname
nodename is kali, release is 4.19.0-kali4-amd64, version is #1 SMP Debian 4.19.28-2kali1 (2019-03-18), machine is x86_64

uname 函数

示例代码通过调用 uname 函数来获取信息,uname 函数部分 manual 信息摘录如下:

       #include <sys/utsname.h>

       int uname(struct utsname *buf);

DESCRIPTION
       uname() returns system information in the structure pointed to by buf.  The utsname struct is defined in <sys/utsname.h>:

           struct utsname {
               char sysname[];    /* Operating system name (e.g., "Linux") */
               char nodename[];   /* Name within "some implementation-defined
                                     network" */
               char release[];    /* Operating system release (e.g., "2.6.28") */
               char version[];    /* Operating system version */
               char machine[];    /* Hardware identifier */
           #ifdef _GNU_SOURCE
               char domainname[]; /* NIS or YP domain name */
           #endif
           };

       The length of the arrays in a struct utsname is unspecified (see NOTES); the fields are terminated by a null byte ('\0').

manual 中没有指定 utsname 结构体不同字段的大小,但 c 语言的数组定义必须确定大小。manual 中提到了历史原因,相关信息摘录如下:

   C library/kernel differences
       Over time, increases in the size of the utsname structure have led to three successive versions of uname(): sys_olduname() (slot __NR_oldolduname), sys_uname() (slot  __NR_olduname),  and  sys_newu‐
       name()  (slot  __NR_uname).  The first one used length 9 for all fields; the second used 65; the third also uses 65 but adds the domainname field.  The glibc uname() wrapper function hides these de‐
       tails from applications, invoking the most recent version of the system call provided by the kernel.

libc 库的 utsname.h 头文件示例

我的虚拟机中,sys/utsname.h 文件路径为 /usr/include/x86_64-linux-gnu/bits/utsname.h,utsname 结构体定义如下:

/* Structure describing the system and machine. */
struct utsname
  { 
   
    /* Name of the implementation of the operating system. */
    char sysname[_UTSNAME_SYSNAME_LENGTH];

    /* Name of this node on the network. */
    char nodename[_UTSNAME_NODENAME_LENGTH];

    /* Current release level of this implementation. */
    char release[_UTSNAME_RELEASE_LENGTH];
    /* Current version level of this release. */
    char version[_UTSNAME_VERSION_LENGTH];

    /* Name of the hardware type the system is running on. */
    char machine[_UTSNAME_MACHINE_LENGTH];

#if _UTSNAME_DOMAIN_LENGTH - 0
    /* Name of the domain of this node on the network. */
# ifdef __USE_GNU
    char domainname[_UTSNAME_DOMAIN_LENGTH];
# else
    char __domainname[_UTSNAME_DOMAIN_LENGTH];
# endif
#endif
  };

_UTSNAME_DOMAIN_LENGTH/usr/include/x86_64-linux-gnu/bits/utsname.h 中被定义为 65。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/11091.html

(0)

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信