【Linux系统编程】Linux系统编程学习笔记
发布日期:2021-05-08 05:10:57 浏览次数:18 分类:精选文章

本文共 3306 字,大约阅读时间需要 11 分钟。

系统参数与选项

1.1. getopt()

getopt() 是 C 语言中用于处理命令行参数的重要函数,主要用于解析程序的选项和参数。它来源于 <unistd.h> 头文件,编写程序时务必包含该头文件。

函数原型

int getopt(int argc, char * const argv[], const char * optstring);
  • argc:主函数的两个整型参数,通常是 main 函数的返回值。
  • argv:指向命令行参数的数组,argv[0] 通常是程序名称。
  • optstring:选项字符串,定义了哪些选项可以被程序接受。

返回值

getopt() 函数返回以下值:

  • 0:表示已经处理完所有选项参数。
  • 1 到 126:表示选项字符,-? 表示未知选项,-: 表示必需参数。
  • -1:表示错误或无效选项。

内部变量

getopt() 函数定义了一些全局变量:

  • extern char * optarg;:保存当前选项参数。
  • extern int optind;:保存当前选项参数的位置。
  • extern int opterr;:判断是否输出错误信息。
  • extern int optopt;:存储未知选项的字符。

选项字符串解析

选项字符串由 -: 组成,表示不同的选项类型:

  • -a-b 等短选项。
  • -:file--file 长选项。
  • --help--version 内建选项。

示例代码

#include 
#include
int main(int argc, char **argv) {
int opt;
while ((opt = getopt(argc, argv, ":a::b:c:")) != -1) {
switch (opt) {
case 'a': printf("option a %s\n", optarg); break;
case 'b': printf("option b %s\n", optarg); break;
case 'c': printf("option c %s\n", optarg); break;
case '?': printf("UNKNOWN %c\n", optopt); break;
case ':': printf("LESS OPT %c\n", optopt); break;
default: break;
}
}
return 0;
}

2. 环境管理

2.1. extern char **environ

environ 是一个全局变量,存储了所有环境变量的值。可以通过它获取或修改环境变量。

获取所有环境变量

#include 
#include
int main(int argc, char *argv[]) {
char **envp = environ;
char **p = envp;
while (*p != NULL && !strncmp(*p, "PATH=", 4)) {
printf("%s\n", *p);
p++;
}
return 0;
}

2.2. getenv()

getenv() 函数用于获取特定环境变量的值。

char *getenv(const char *name);
  • name:环境变量的名称。
  • 返回值:成功返回对应值,失败返回 NULL

2.3. setenv() 和 unsetenv()

setenv() 用于设置或修改环境变量:

int setenv(const char *name, const char *value, int overwrite);
  • value:新值。
  • overwrite:如果已有该变量,是否覆盖。

unsetenv() 则用于删除环境变量:

int unsetenv(const char *name);

2.4. clearenv()

clearenv() 用于清除所有环境变量:

int clearenv(void);

3. 内存管理

3.1. 内存分配与释放

Linux 系统提供了多种内存管理函数,主要来自 <stdlib.h><malloc.h>

malloc()

void *malloc(unsigned int num_bytes);

分配一块大小为 num_bytes 的内存,返回指针。

calloc()

void *calloc(size_t nmemb, size_t size);

分配一块大小为 nmemb * size 的内存,并初始化为 0。

realloc()

void *realloc(void *mem_address, unsigned int newsize);

调整已有内存块的大小,返回新指针。

free()

void free(void *ptr);

释放已分配的内存。

内存分配原理

内存分配主要通过 brk()mmap() 系统调用实现:

  • brk() 调用修改进程的数据段尾指针,扩展或收缩内存。
  • mmap() 在堆和栈之间映射物理内存。

4. 错误处理

4.1. errno

errno 是一个全局变量,存储最新发生的错误代码。不同系统调用会设置不同的错误码。

常用错误代码

  • EPERM:权限不足。
  • ENOENT:文件或目录不存在。
  • EINTR:系统调用被中断。
  • EAGAIN:重试操作。
  • EBADF:文件描述符无效。

错误输出函数

void perror(const char *s);

输出错误信息,结合 errno


5. 文件I/O

5.1. 目录

目录是文件系统的基本结构单元,包含文件名和 inode 节点。

目录操作

  • chdir():改变当前目录。
  • getcwd():获取当前目录。
  • rmdir():删除目录。
  • mkdir():创建目录。
  • opendir():打开目录。
  • readdir():读取目录内容。

文件描述符

文件描述符是程序与文件进行 I/O 操作的接口,常用函数:

  • open():打开文件或设备。
  • read():读取文件。
  • write():写入文件。
  • close():关闭文件。

6. 时间管理

6.1. 时间类型

  • time_t:表示从 1970 年以来的秒数。
  • struct timeval:精确到微秒。
  • struct tm:包含时间的各个部分。

时间操作函数

  • time():获取当前时间。
  • gettimeofday():获取高精度时间。
  • mktime():将 struct tm 转换为 time_t

7. 信号

7.1. 信号机制

信号是程序执行中的异步事件,例如终止、错误、定时器等。处理信号需要注册信号函数。

信号处理函数

void func(int sig) {
// 处理信号
}
int main() {
struct sigaction act;
act.sa_handler = func;
sigaction(SIGINT, &act, NULL);
// ...
}

实时信号

实时信号(SIGRT*) 通常用于高优先级任务,不能被阻塞或忽略。


8. POSIX 定义头文件

POSIX 标准定义了许多系统函数,常用头文件包括:

  • <dirent.h>:目录项。
  • <fcntl.h>:文件控制。
  • <signal.h>:信号处理。
  • <sys/types.h>:系统数据类型。
  • <unistd.h>:用户和群组信息。

通过以上内容,可以全面了解 Linux 系统的底层功能和 API。

上一篇:【Linux驱动开发】PS2游戏手柄驱动开发与输入子系统框架
下一篇:【单片机开发】STM32简易示波器开发

发表评论

最新留言

做的很好,不错不错
[***.243.131.199]2025年04月10日 05时33分10秒