The Linux Programming Interface 03 System Programming Concepts 系统编程观念
来源:互联网 发布:电视直播哪个软件最好 编辑:程序博客网 时间:2024/04/29 10:03
The Linux Programming Interface
System Programming Concepts
(1) 本节主要概括
Whenever we make a system call or call a library function, we should always check the return status of the call in order to determine if it was successful. We describe how to perform such checks, and present a set of functions that are used in most of the example programs in this book to diagnose errors from system calls and library functions.
(2)系统调用
比较难,设计操作寄存器,抽象理解。
If the return of the system call service routine indicated an error, the wrapper function sets the global variable errno using this value. The wrapper function then returns to the caller, providing an integer return value indicating the success or failure of the system call.
When a negative value is returned, the C library wrapper function negates it(to make it positive), copies the result into errno, and returns -1 as the function result of the wrapper to indicate an error to the calling program.
(3) 打印glibc的版本,可以调用gnu_get_libc_version()函数
#include <stdio.h> #include <gnu/libc-version.h> int main() { printf("%s\n", gnu_get_libc_version()); return 0; }
输出: 2.19
(4)Handing Errors from System Calls and Library Functions
Many hours of debugging time can be wasted because a check was not made on the status return of a system call or library function that "couldn't possibly fail".
fd = open(pathname, flags, mode);
if (fd == -1) {
/* Code to handle the error */
}
When a system call fails, it sets the global integer variable errno to a positive value that identifies the specific error. Including the <errno.h> header file provides a declaration of errno, as well as a set of constants for the various error numbers.
(5) commence 开始,着手
(6) errno
cnt = read(fd, buf, numbytes);if (cnt == -1) { if (errno == EINTR) {fprintf(stderr, "read was interrrupted by a signal\n"); } else { /* Some other error occurred */}
Therefore, when checking for an error, we should always first check if the function return value indicates an error, and only then examine errno to determine the cause of the error.
(7) perror and strerror
A common course of action after a failed system call is to print an error message based on the errno value. The perror() and strerror() library functions are provided for this purpose.
fd = open(pathname, flags, mode);if (fd == -1) { perror("open"); exit(EXIT_FAILURE);}
1 #include <stdio.h> 2 #include <gnu/libc-version.h> 3 #include <sys/stat.h> 4 #include <fcntl.h> 5 #include <stdlib.h> 6 7 int main() { 8 printf("%s\n", gnu_get_libc_version()); 9 int fd = open("tmp/temp", O_WRONLY|O_CREAT); 10 if (fd == -1) { 11 perror("open"); 12 exit(EXIT_FAILURE); 13 } 14 return 0; 15 }
输出:
2.19
open: No such file or directory
(8) 通过库函数处理错误
1 #include <stdio.h> 2 #include <gnu/libc-version.h> 3 #include <sys/stat.h> 4 #include <fcntl.h> 5 #include <stdlib.h> 6 #include <errno.h> 7 #include <string.h> 8 9 int main() { 10 printf("%s\n", gnu_get_libc_version()); 11 int fd = open("tmp/temp", O_WRONLY|O_CREAT); 12 if (fd == -1) { 13 perror("open"); 14 char *str = strerror(errno); 15 printf("%s\n", str); 16 exit(EXIT_FAILURE); 17 } 18 return 0; 19 }
output:
wang@wang:~/test$ ./a.out
2.19
open: No such file or directory
No such file or directory
(09) 作者定义了一些方便使用的函数,比如getNum(), gnFail(), 有空可以分析其源码定义。
(10) 移植相关定义
Defining multiple macros is additive, so that we could, for example, use the following cc command to explicitly select the same macro setting as are provided by default:
$ cc -D_POSIX_SOURCE -D_POSIX_C_SOURCE=199506 -D_BSD_SOURCE -D_SVID_SOURCE prog.c
(11) system date types
Each of these types is defined using the C typedef feature. For example, the pid_t data type is intended for representing process IDs, and on Linux/x86-32 this type is defined as follows:
typedef int pid_t;
Most of the standard system data types have names ending in _t. Many of them are declared in the header file <sys/types.h>.
打印类型
1 #include <stdio.h> 2 #include <sys/types.h> 3 #include <unistd.h> 4 5 int main() { 6 pid_t mypid; 7 mypid = getpid(); 8 printf("My PID is %ld\n", (long)mypid); 9 return 0; 10 }
output:
wang@wang:~/test$ ./a.out
My PID is 1226
(12)不同的系统中参数存放的顺序可能不同
struct sembuf { unsigned short sem_num; short sem_op; short sem_flg;}(13)
Therefore, this macro might not be present on some UNIX implementations. In order to portably handle such possibilities, we can use the C preprocessor #ifdef directive, as in the following example:
#ifdef WCOREDUMP
/* Use WCOREDUMP() macro */
#endif
(14) 总结
System call allow processes to request services from the kernel. Even the simplest system calls have a significant overhead by comparison with a user-space function call, since the system must temporarily switch to kernel mode to execute the system call, and the kernel must verify system call arguments and transfer data between user memory and kernel memory.
The standard C library provides a multitude of library functions that perform a wide range of tasks. Some library functions employ system calls to do their work; others perform tasks entirely within user space. On Linux, the usual standard C library implementation that is used is glibc.
Most system calls and library functions return a status indicating whether a call has succeeded or failed. Such status returns should always be checked.
We introduced a number of functions that we have implemented for use i the example programs in this book. The tasks performed by these function include diagnosing errors and parsing command-line arguments.
We discussed various guidelines and techniques that can help us write portable system programs that run on any standards-conformant system.
When compiling an application, we can define various feature test macros that control the definition exposed by header files. This is useful if we want to ensure that a program conforms to some formal or implementation -defined standards.
We can improve the portability of system programs by using the system data types defined in various standards, rather than native C types. SUSv3 specifies a wide range of system data types that an implementation should support and that an application should employ.
(15)课后练习
主要是使用reboot函数的第二个参数
man 2 reboot
This system call will fail (with EINVAL) unless magic equals
LINUX_REBOOT_MAGIC1 (that is, 0xfee1dead) and magic2 equals
LINUX_REBOOT_MAGIC2 (that is, 672274793). However, since 2.1.17 also
LINUX_REBOOT_MAGIC2A (that is, 85072278) and since 2.1.97 also
LINUX_REBOOT_MAGIC2B (that is, 369367448) and since 2.5.71 also
LINUX_REBOOT_MAGIC2C (that is, 537993216) are permitted as values for
magic2. (The hexadecimal values of these constants are meaningful.)
打印LINUX_REBOOT_MAGIC2
#include <unistd.h>#include <linux/reboot.h>#include <stdio.h>int main() { printf("%lx\n", (long)LINUX_REBOOT_MAGIC2); return 0;}
输出:
wang@wang:~/src/workspace/test$ ./a.out
28121969
使用reboot重启电脑,注意需要root权限。
#include <unistd.h>#include <linux/reboot.h>#include <stdio.h>int main() { printf("%lx\n", (long)LINUX_REBOOT_MAGIC2); reboot(RB_AUTOBOOT); return 0;}
- The Linux Programming Interface 03 System Programming Concepts 系统编程观念
- The Linux Programming Interface 02 Fundamental Concepts 基本概念
- The Linux Programming Interface 11 System Limits And Options 系统限制和选择
- The Linux Programming Interface 12 System And Process Information 系统和进程信息
- The Linux Programming Interface 16
- The Linux Programming Interface - A Linux and UNIX System Programming Handbook
- The Linux Programming Interface(Linux编程接口)学习计划
- The Linux Programming Interface 00 preface 序言
- The Linux Programming Interface 06 Process 进程
- The Linux Programming Interface 10 Time 时间
- Understanding the concepts of Object Oriented Programming
- 书评:Linux System Programming
- Linux system programming
- Linux System Programming -- Appendix
- The Linux Programming Interface 07 Memory Allocation 分配内存
- The Linux Programming Interface 09 Process Credentials 进程凭证
- The Linux Programming Interface 14 File Systems 文件系统
- The Linux Programming Interface 15 File Attributes 文件属性
- Android 面试题整理
- 【知识整理】Hibernate的HQL检索方式使用入门
- beego.AppConfig.String取不出默认配置的值
- PAT甲级1036. Boys vs Girls (25)
- Android Binder机制(超级详尽)
- The Linux Programming Interface 03 System Programming Concepts 系统编程观念
- 区分HTML中cite标签,q标签,blockquote标签
- maven3实战之maven使用入门
- 在Express的页面模板中的变量的定义与使用总结
- git錯誤信息
- groovy 与 java 差异 (1)
- PCA(Principal Components Analysis)
- 竖式问题 sprintf
- 【Python专题】 使用Py3及Pycharm的一些小问题(仅个人问题记录)