• coreutils5.0 uname命令和源码分析


      uname   /* 默认输出内核名。和uname -s一样 */


      -a, --all  /* 按以下顺序打印所有信息 */
      -s  /* 打印内核名称 */
      -n  /* 打印主机名 */
      -r  /* 打印内核版本发行号 */
      -v  /* 打印内核版本 */
      -m  /* 打印机器硬件名称 */
      -p  /* 打印CPU类型 */
      -i  /* 打印硬件平台 */
      -o   /* 打印操作系统 */

    1. /* uname -- print system information
    2. Copyright 1989, 1992, 1993, 1996, 1997, 1999, 2000, 2001, 2002 Free
    3. Software Foundation, Inc.
    4. This program is free software; you can redistribute it and/or modify
    5. it under the terms of the GNU General Public License as published by
    6. the Free Software Foundation; either version 2, or (at your option)
    7. any later version.
    8. This program is distributed in the hope that it will be useful,
    9. but WITHOUT ANY WARRANTY; without even the implied warranty of
    10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    11. GNU General Public License for more details.
    12. You should have received a copy of the GNU General Public License
    13. along with this program; if not, write to the Free Software Foundation,
    14. Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
    15. /* Written by David MacKenzie */
    16. #include
    17. #include
    18. #include
    19. #include
    20. #include
    21. #if HAVE_SYSINFO && HAVE_SYS_SYSTEMINFO_H
    22. # include
    23. #endif
    24. #if HAVE_SYSCTL && HAVE_SYS_SYSCTL_H
    25. # include /* needed for OpenBSD 3.0 */
    26. # include
    27. # ifdef HW_MODEL
    28. # ifdef HW_MACHINE_ARCH
    29. /* E.g., FreeBSD 4.5, NetBSD 1.5.2 */
    30. # define UNAME_HARDWARE_PLATFORM HW_MODEL
    31. # define UNAME_PROCESSOR HW_MACHINE_ARCH
    32. # else
    33. /* E.g., OpenBSD 3.0 */
    34. # define UNAME_PROCESSOR HW_MODEL
    35. # endif
    36. # endif
    37. #endif
    38. #include "system.h"
    39. #include "error.h"
    40. #include "closeout.h"
    41. /* The official name of this program (e.g., no `g' prefix). */
    42. #define PROGRAM_NAME "uname"
    43. #define AUTHORS "David MacKenzie"
    44. /* 用于修改toprint的值 */
    45. /* 内核名称 */
    46. #define PRINT_KERNEL_NAME 1
    47. /* 主机名 */
    48. #define PRINT_NODENAME 2
    49. /* 内核发行号 */
    50. #define PRINT_KERNEL_RELEASE 4
    51. /* 内核版本 */
    52. #define PRINT_KERNEL_VERSION 8
    53. /* 硬件名 */
    54. #define PRINT_MACHINE 16
    55. /* CPU类型 */
    56. #define PRINT_PROCESSOR 32
    57. /* 硬件平台 */
    58. #define PRINT_HARDWARE_PLATFORM 64
    59. /* 操作系统 */
    60. #define PRINT_OPERATING_SYSTEM 128
    61. /* 保存程序名 = argv[0] */
    62. char *program_name;
    63. /* 长选项结构体 */
    64. static struct option const long_options[] =
    65. {
    66. {"all", no_argument, NULL, 'a'}, /* "长选项名称","选项:no_argument代表该长选项无需参数","元素三为NULL时,getopt将直接返回元素四,不为空时参数三将保存元素4" */
    67. {"kernel-name", no_argument, NULL, 's'},
    68. {"sysname", no_argument, NULL, 's'}, /* 即将弃用,该源码是5.0,不知道9.0是否以弃用. */
    69. {"nodename", no_argument, NULL, 'n'},
    70. {"kernel-release", no_argument, NULL, 'r'},
    71. {"release", no_argument, NULL, 'r'}, /* 即将弃用,该源码是5.0,不知道9.0是否以弃用. */
    72. {"kernel-version", no_argument, NULL, 'v'},
    73. {"machine", no_argument, NULL, 'm'},
    74. {"processor", no_argument, NULL, 'p'},
    75. {"hardware-platform", no_argument, NULL, 'i'},
    76. {"operating-system", no_argument, NULL, 'o'},
    77. {GETOPT_HELP_OPTION_DECL},
    78. {GETOPT_VERSION_OPTION_DECL},
    79. {NULL, 0, NULL, 0} /* 没有参数时返回0 */
    80. };
    81. /* 传入的命令行参数的错误函数,传入不支持的参数就调用该函数 */
    82. void
    83. usage (int status)
    84. {
    85. if (status != 0)
    86. fprintf (stderr, _("Try `%s --help' for more information.\n"),
    87. program_name);
    88. else
    89. {
    90. /* 调用错误函数时,提示该命令用法,命令没有参数时将和-s一样 */
    91. printf (_("Usage: %s [OPTION]...\n"), program_name);
    92. fputs (_("\
    93. Print certain system information. With no OPTION, same as -s.\n\
    94. \n\
    95. /* 按以下顺序打印所有信息 */
    96. -a, --all print all information, in the following order:\n\
    97. /* 打印内核名称 */
    98. -s, --kernel-name print the kernel name\n\
    99. /* 打印主机名 */
    100. -n, --nodename print the network node hostname\n\
    101. /* 打印内核版本发行号 */
    102. -r, --kernel-release print the kernel release\n\
    103. "), stdout);
    104. fputs (_("\
    105. /* 打印内核版本 */
    106. -v, --kernel-version print the kernel version\n\
    107. /* 打印机器硬件名称 */
    108. -m, --machine print the machine hardware name\n\
    109. /* 打印CPU类型 */
    110. -p, --processor print the processor type\n\
    111. /* 打印硬件平台 */
    112. -i, --hardware-platform print the hardware platform\n\
    113. /* 打印操作系统 */
    114. -o, --operating-system print the operating system\n\
    115. "), stdout);
    116. fputs (HELP_OPTION_DESCRIPTION, stdout);
    117. fputs (VERSION_OPTION_DESCRIPTION, stdout);
    118. printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
    119. }
    120. exit (status);
    121. }
    122. /* Print ELEMENT, preceded by a space if something has already been
    123. printed. */
    124. static void
    125. print_element (char const *element)
    126. {
    127. static int printed;
    128. if (printed++)
    129. putchar (' ');
    130. fputs (element, stdout);
    131. }
    132. int
    133. main (int argc, char **argv)
    134. {
    135. int c;
    136. static char const unknown[] = "unknown";
    137. /* Mask indicating which elements to print. */
    138. /* 指示要打印哪些元素的掩码(最后用该值判断用户需要输出什么信息) */
    139. unsigned toprint = 0;
    140. /* 程序初始化 */
    141. program_name = argv[0]; /* 程序名 */
    142. setlocale (LC_ALL, ""); /* 获取系统编码、地区代码等信息 */
    143. bindtextdomain (PACKAGE, LOCALEDIR);
    144. textdomain (PACKAGE);
    145. atexit (close_stdout);/* 出口函数 */
    146. /* 解析命令行参数 */
    147. while ((c = getopt_long (argc, argv, "asnrvmpio", long_options, NULL)) != -1) /* c保存用户传入的参数 */
    148. {
    149. /* 判断用户传入的函数来修改toprint的值 */
    150. switch (c)
    151. {
    152. case 0:
    153. break;
    154. case 'a':
    155. toprint = -1;
    156. break;
    157. /* 内核名称,值=1 */
    158. case 's':
    159. toprint |= PRINT_KERNEL_NAME;
    160. break;
    161. /* 主机名称,值=2 */
    162. case 'n':
    163. toprint |= PRINT_NODENAME;
    164. break;
    165. /* 内核发行号,值=4 */
    166. case 'r':
    167. toprint |= PRINT_KERNEL_RELEASE;
    168. break;
    169. /* 内核版本,值=8 */
    170. case 'v':
    171. toprint |= PRINT_KERNEL_VERSION;
    172. break;
    173. /* 硬件名,值=16 */
    174. case 'm':
    175. toprint |= PRINT_MACHINE;
    176. break;
    177. /* CPU类型,值=32 */
    178. case 'p':
    179. toprint |= PRINT_PROCESSOR;
    180. break;
    181. /* 硬件平台,值=64 */
    182. case 'i':
    183. toprint |= PRINT_HARDWARE_PLATFORM;
    184. break;
    185. /* 操作系统,值=128 */
    186. case 'o':
    187. toprint |= PRINT_OPERATING_SYSTEM;
    188. break;
    189. /* 在system.h内定义 在这case内会exit退出程序 */
    190. case_GETOPT_HELP_CHAR;
    191. /* 在system.h内定义 在这case内会exit退出程序 */
    192. case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
    193. default:
    194. usage (EXIT_FAILURE); /* 如果以上case都没有触发的话,调用usage帮助函数,退出程序,EXIT_FAILURE的值为1,定义在stdlib */
    195. }
    196. }
    197. /* getopt调用的次数不等于main传入的参数就报错。用来测试传入的参数是否全部都getopt成功。因为每次调用一次getopt都会使optind +1 */
    198. if (optind != argc)
    199. usage (EXIT_FAILURE);
    200. /* 不带参数默认转成内核名称 */
    201. if (toprint == 0)
    202. toprint = PRINT_KERNEL_NAME;
    203. /* 参数值==1 | 2 | 4 | 8 | 16 进入该if */
    204. if (toprint
    205. & (PRINT_KERNEL_NAME | PRINT_NODENAME | PRINT_KERNEL_RELEASE
    206. | PRINT_KERNEL_VERSION | PRINT_MACHINE))
    207. {
    208. struct utsname name; /* 获取系统相关信息的结构体 */
    209. if (uname (&name) == -1) /* 填充ustname结构 */
    210. error (EXIT_FAILURE, errno, _("cannot get system name")); /* 无法获取系统名称 */
    211. if (toprint & PRINT_KERNEL_NAME)
    212. print_element (name.sysname);
    213. if (toprint & PRINT_NODENAME)
    214. print_element (name.nodename);
    215. if (toprint & PRINT_KERNEL_RELEASE)
    216. print_element (name.release);
    217. if (toprint & PRINT_KERNEL_VERSION)
    218. print_element (name.version);
    219. if (toprint & PRINT_MACHINE)
    220. print_element (name.machine);
    221. }
    222. /* 参数值==32 */
    223. if (toprint & PRINT_PROCESSOR)
    224. {
    225. char const *element = unknown;
    226. #if HAVE_SYSINFO && defined SI_ARCHITECTURE
    227. {
    228. static char processor[257];
    229. if (0 <= sysinfo (SI_ARCHITECTURE, processor, sizeof processor))
    230. element = processor;
    231. }
    232. #endif
    233. #ifdef UNAME_PROCESSOR
    234. if (element == unknown)
    235. {
    236. static char processor[257];
    237. size_t s = sizeof processor;
    238. static int mib[] = { CTL_HW, UNAME_PROCESSOR };
    239. if (sysctl (mib, 2, processor, &s, 0, 0) >= 0)
    240. element = processor;
    241. }
    242. #endif
    243. print_element (element);
    244. }
    245. /* 参数值==64 */
    246. if (toprint & PRINT_HARDWARE_PLATFORM)
    247. {
    248. char const *element = unknown;
    249. #if HAVE_SYSINFO && defined SI_PLATFORM
    250. {
    251. static char hardware_platform[257];
    252. if (0 <= sysinfo (SI_PLATFORM,
    253. hardware_platform, sizeof hardware_platform))
    254. element = hardware_platform;
    255. }
    256. #endif
    257. #ifdef UNAME_HARDWARE_PLATFORM
    258. if (element == unknown)
    259. {
    260. static char hardware_platform[257];
    261. size_t s = sizeof hardware_platform;
    262. static int mib[] = { CTL_HW, UNAME_HARDWARE_PLATFORM };
    263. if (sysctl (mib, 2, hardware_platform, &s, 0, 0) >= 0)
    264. element = hardware_platform;
    265. }
    266. #endif
    267. print_element (element);
    268. }
    269. /* 参数值==128 */
    270. if (toprint & PRINT_OPERATING_SYSTEM)
    271. print_element (HOST_OPERATING_SYSTEM);
    272. putchar ('\n');
    273. exit (EXIT_SUCCESS);
    274. }

    getopt_long解析用户传入参数后并保存在toprint,调用uname填充ustname结构体,判断torint输出对应的信息

    问1:-a = -1时是怎么输出所有。是不是-1在&别的常量时if判断为true所以能输出所有。

    因为发现5.0和新的源码差距太大了,所以man shuf翻到最下面查看了我linux的coreutils是8.32,所以去看8.32了,这个问题等8.32的时候在解决了

  • 相关阅读:
    个人记录jenkins编译ios过程 xcode是9.4.1
    容器云安全挑战和攻防应对
    【web-攻击验证机制】(3.2.1)验证机制设计缺陷:密码保密性不强、蛮力攻击登录、详细的失败消息
    计算机毕业设计之java+ssm的校园旧书交易交换平台
    数据密码学
    GPT-3在化学中进行低数据发现是否足够?
    数据结构——排序
    Kubernetes中Pod的扩缩容介绍
    docker部署rabbitmq的坑
    基于ROS的蛇形机器人基本仿生运动与自主爬台阶控制
  • 原文地址:https://blog.csdn.net/qq2260079443/article/details/126652990