APUE3学习笔记-第一章-UNIX基础知识

本文介绍了UNIX环境下编程的基础概念,包括登录流程、shell命令行解释器的功能、文件系统的组织结构、输入输出流的管理、进程控制的基本函数、出错处理机制、用户标识与权限管理、信号的概念及处理方式、时间值的表示、以及系统调用和库函数的区别。

——上善若水,大道至简

UNIX体系结构

UNIX体系结构


登录

在/etc/passwd中查看登录名
文件中7个字段依次是:
登录名、登录口令、数字用户ID、数字组ID、注释字段、起始目录、shell程序
root:x:0:0:root:/root:/bin/bash

shell

shell

用户登录后,系统通常先显示一些系统信息,然后用户就可以向shell程序键入命令。
shell是一个命令行解释器,它读取用户输入,然后执行命令。

文件和目录

UNIX文件系统是目录和文件 的一种层次结构。
所有东西的起点成文根目录,根目录:“/”。
.(称为点),..(称为点点),点指向当前目录,点点指向父目录,
在最高层次的根目录中,点与点点相同。
绝对路径以根目录开头,相对路径以当前目录开头。
当前工作目录指进程的工作目录。
起始目录为登录时的工作目录。
ls命令查看目录下的所有文件的名字。

输入和输出

当内核打开一个现有文件或创建一个新文件时,都会返回一个文件描述符。
文件描述符通常是一个小的非负整数,在读、写文件时,可以使用该描述符。
当运行一个新程序时,shell会为其打开3个文件描述符,
即标准输入、标准输出、标准错误,通常这3个描述符链接向终端。
标准输入重定向: <
标准输出重定向: >

程序和进程

程序是一个可执行文件,内核使用exec函数将程序读入内存,并执行程序。
程序的执行实例称为进程。
每个进程都有唯一的数字标识符,称为进程ID。
进程控制的主要函数:forkexecwaitpid。
一个进程只有一个控制线程,

出错处理

文件<errno.h>中定义了大约15中不同的errno值,当系统函数出错时,<errno.h>
stderror(int errnum)可以将errnum(通常就是errno的值)映射为一个出错消息字符串,并返回字符串的指针。
通过perror(const char *msg)基于当前的errno值产生一条出错消息,
它首先输出msg指向的字符串,然后是一个冒号一个空格,接着是对应的出错消息。

用户标识

口令文件登录项中的用户ID和组ID,用于系统管理员管理登录用户的权限。
每一个用户有一个唯一的用户ID,内核通过检验用户ID确定该用户是否有执行某些操作的权限。
每个用户可以有多个组ID,组被用于将若干用户集合到项目中去,允许组内成员共享资源(如访问文件)。
组文件/etc/group。
调用getuid(),getgid()可以分别返回用户ID和组ID。

信号


信号用于通知进程发生了某种情况。
处理信号的三种方式:1.忽略信号 2。默认方式处理 3.提供处理函数,信号发生时调用。
捕捉信号使用signal函数,如下:
static void sig_int(int signo)
{
    printf("this is a signal\n%% ");
}

int main(void)
{
    if(signal(SIGINT, sig_int) == SIG_ERR)
        err_sys("signal error");

    ……

}

当产生SIGINT信号时调用sig_int。


时间值


日历时间为自UTC1970年1月1日 00:00:00以来的秒数积累值。
数据类型 time_t 用于保存这种时间值。
UNIX为一个进程维护了3个进程时间值:
时钟时间、用户CPU时间、系统CPU时间

系统调用和库函数

内核的直接入口点称为系统调用。
库函数调用了一个或多个系统调用,不是内核入口点。
应用程序既可以调用系统调用也可以调用库函数。


### APUE 第三章 学习笔记 #### 文件 I/O 基础 APUE 的第三章主要讨论了 Unix 系统中的文件 I/O 操作基础。这一章节涵盖了多个重要的概念和技术细节,对于理解如何高效地操作文件至关重要。 #### 打开和关闭文件 为了打开一个文件,程序通常会使用 `open` 或者 `creat` 函数[^1]。这两个函数都返回一个小于零的整数作为错误指示,而成功的调用则返回一个非负整数表示新创建的文件描述符。当不再需要访问某个特定文件时,应该通过调用 `close` 来关闭它。这不仅释放了与该文件关联的操作系统资源,而且也使得这个文件描述符能够被重新利用。 ```c #include <fcntl.h> /* For O_* constants */ #include <unistd.h> /* For open(), close() */ int fd; fd = open("example.txt", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); if (fd >= 0) { // File opened successfully. } // Later... close(fd); ``` #### 文件读写 一旦有了有效的文件描述符,就可以对其进行读取 (`read`) 和写入 (`write`) 操作。这些基本的 I/O 操作允许应用程序直接处理底层的数据流而不必关心具体的设备特性[^2]。 ```c char buffer[BUFSIZ]; ssize_t n; n = read(fd, buffer, BUFSIZ - 1); if (n > 0) { buffer[n] = &#39;\0&#39;; // Null terminate the string printf("%s\n", buffer); } const char *msg = "Hello world!"; write(fd, msg, strlen(msg)); ``` #### 文件定位 除了简单的顺序读写外,还可以改变当前文件偏移量来实现随机访问。这是通过 `lseek` 实现的功能之一,它可以向前或向后移动文件指针的位置以便从不同的位置开始读写数据[^3]。 ```c off_t offset; offset = lseek(fd, SEEK_SET, 0); // Move to beginning of file if (offset != -1L) { // Seek succeeded. } ``` #### 特殊文件类型的支持 Unix 系统支持多种特殊类型的文件对象,比如管道、套接字以及终端设备等。本章还介绍了针对这些不同类型文件的具体 API 接口和支持机制[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值