摘要:前言 在前文中,讲述了一个可靠信号的示例。它分成几个步骤组成( 请参考前文 )。在 Linux 系统编程中,有个方法可以将这些步骤给集成起来,让我们使用起来更加的方便。那就是调用 sigaction 函数。sigaction 函数 原型:int sigaction (int signo, con...
阅读全文
摘要:前言 曾经的 UNIX 系统中,信号的不可靠的。什么是不可靠?就是信号丢失呗。那什么是信号丢失?就是当系统正在处理某个事务的时候,如果收到了某个信号,但它不能及时处理这个信号,那么只能忽略掉此信号。 而在可靠信号机制中,如果发生了上述情况,则要求系统处理完当前的事务后,还能够找回丢失的那个信号。...
阅读全文
摘要:前言 前文介绍了最基本的信号接收和处理,但这有无可能带来一些问题呢?本文将通过两个思考,来分析可能带来的问题以及解决方法。思考一:中断的系统调用 如果用户正在执行系统调用,如 write read。如果这个时候程序跳转到了信号处理函数后返回,则是否重新执行这个系统调用?结论 这要分情况讨论:如...
阅读全文
摘要:前言 要想掌握 Linux 系统编程,自然要好好学学其信号机制。本文介绍一个简单的信号接收处理程序,为后面继续深入学习信号机制打下基础。什么是信号 信号是软件中断,它提供一种处理异步事件的方法。信号产生的条件 1. 当用户按某些终端按键时。比如:Ctrl + D / Ctrl + C 等 2...
阅读全文
摘要:前言 在 Linux 中,一个正在执行的程序往往由各种各样的进程组成,这些进程除了父子关系,还有其他的关系。依赖于这些关系,所有进程构成一个整体,给用户提供完整的服务( 考虑到了终端,即与用户的交互 )。本文将详细描述 Linux 中的进程结构。进程结构 上图所描述的是为了给用户提供一次完整...
阅读全文
摘要:前言 在很多时候,创建一个子进程的目的,仅是让它去执行一些其他已经编译好了的程序。本文将介绍其简单实现方法。execl 函数族 为何称为函数族 --- 是因为根据其参数格式,是否传递环境变量等,execl 函数有几个变体。各种变体的原型请读者自行参考资料。 但它们的作用都一样,那就是用一个全新...
阅读全文
摘要:前言 如果父进程没有结束,而子进程终止了。那么在父进程调用 wait 函数回收这个子进程或者父进程终止以前,这个子进程将一直是僵尸进程。本文将提供两种方法处理这个问题。方法一:父进程回收法 wait函数将使其调用者阻塞,直到其某个子进程终止。故父进程可调用wait函数回收其僵尸子进程。除此之外,...
阅读全文
摘要:前言 Linux 是多道处理系统,当然能够在同一段时间内处理多个程序。本文将介绍具体该如何操作。fork 函数 此函数的作用是创建一个子进程,调用后,调用进程和创建的新进程就会并发执行( 从调用处开始 )。它调用一次,却返回两次,一次是在调用进程内,返回子进程ID,另一次是在创建的新进程( 子进...
阅读全文
摘要:前言 每个进程都有其使用资源的一个限制,这些资源通常是在进程初始化时由进程 0 所建立的,然后由每个后续进程继承。本文将介绍如何获取并修改进程的资源限制。获取资源限制函数:getrlimit 原型:int getrlimit (int resource, struct rlimit *rlptr...
阅读全文
摘要:前言 在 UNIX Like 系统中,存有各类系统/应用程序的环境变量,可通过修改之改变系统/应用程序的执行效果;除此之外,用户还可以定义自己的环境变量,供自己写的程序使用。本文将说明如何在程序中设置以及读取这些环境变量。获取环境变量函数:getenv 原型:char * getenv (con...
阅读全文
摘要:前言 C语言程序的执行必定需要耗费一定的资源,也就是说,程序在计算机内部的映像不可能就单单代码。本文将讲解C语言程序在计算机内部的存在方式。程序存储空间 正文段:程序的机器指令部分 初始化的数据:已经明确赋值的变量的值 非初始化的数据:为赋值的变量的值 栈:存放自动变量以及每次函数调用...
阅读全文
摘要:前言 在 Linux 中,系统数据文件大都不能直接用编辑的方式读取。如此设计一方面是从安全性考虑,另一方面则是从文件检索效率考虑。本文将以口令文件 passwd 为例讲解读取 Linux 中系统数据文件的方法。基本步骤 1. 包含读写该系统数据文件的专用头文件 ( 如读写口令文件要包含 pwd....
阅读全文
摘要:前言 在之前,学习了 read write 这样的不带缓冲IO函数。而本文将讲解标准IO库中,带缓冲的IO函数。为什么要有带缓冲IO函数 标准库提供的带缓冲IO函数是为了减少 read 和 write 函数调用次数而设计的。因为每次调用 read 和 write 函数系统都会中断并陷入内核,增加了CPU的负担。三大缓冲类型 1. 全缓冲 在填满标准IO缓冲区后才进行实际IO操作。 2. 行缓冲 在输入和输出过程中遇到换行符时,执行实际IO操作。 3. 不缓冲 任何时候的实际读写都是在函数调用时进行,函数调用后结束。代码实现 具体的应用类似于不带缓冲IO函数,只是文件描述符变成...
阅读全文
摘要:前言 前文对 Linux 中的权限进行了较为透彻的分析。而本文,则在前文的基础上,具体说明如何在代码中进行权限控制。 下面的代码涉及到以下几个方面: 1. 创建文件时设置文件权限 2. 修改文件的默认权限 3. 修改已创建文件的权限 在阅读具体实现代码前,请先大致了解如下权限宏。Linux 中的权限宏代码实现 1 #include "apue.h" 2 #include 3 4 #define RWRWRW (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) 5 6 int 7 main(void) 8 { 9 stru...
阅读全文
摘要:前言 上篇随笔讲述了Linux中权限的大致实现机制以及目录权限的相关规则。本文将讲解Linux中的三种特殊权限:SUID,SGID,Sticky权限。看完这两篇文章,你一定会对Linux的权限有个更深的认识。SUID 当一个文件有了SUID权限,则其他用户使用这个文件的时候,可以临时获取到该文件所有者的权限。 该权限比较经典的一个使用例子是passwd程序:每个用户都可以执行这个程序修改自己的密码,但我们知道密码文件的所有者是root且不允许其他用户接触。那怎么修改密码?有办法!我们给这个文件以SUID权限,这样当用户通过修改密码进程使用这个文件时,可以临时获取root权限,从而修改到自...
阅读全文
摘要:前言 在Linux系统中,用户分为三个部分( 所有者 同组人 其他 )。每个部分的权限又可以赋予读/写/执行权限。这样,文件的权限标记一共包含 9 个权限位。好了,很多朋友对于Linux权限的了解就仅限于此了。但,Linux目录权限和文件权限一样吗?内核对于权限的检查过程又是怎样的?如果你不清楚,本文将为你解惑。目录权限 1. 目录读权限 目录读权限允许读取目录的文件列表并显示出来,仅仅是允许读取文件列表,对于文件其他信息的读取不保证。 事实上,如果只有读权限没有写权限,那么执行查看目录后显示如下: 2. 目录写权限 如果要在目录里面创建文件,那么就需要写权限,别忘了,也要执行...
阅读全文
摘要:前言 在之前的文章中,描述过如何用 fcntl 函数改变文件的状态标记。但,文件还有很多信息,如文件类型,权限设置,设备编号,访问时间等等。如果要获取这些信息,则使用函数 lstat 可以轻松达到这个目的。 下面的程序将使用该函数获取文件类型信息并判断它的类型。 但在这之前,先要说明文件信息结...
阅读全文
摘要:前言 文件共享是指同时打开一个文件 用 dup 函数能对指定文件描述符再创建一个新的描述符,且这个新的描述符和旧的描述符指向的是同一个文件。 这两种行为有什么区别呢?下面给出的两张文件系统的图形象的解答了这个问题。文件共享 dup创建新描述符 小结 1. dup 函数的这种功能也可以用之前提到的 fctnl 函数来实现:dup( fd ) 等效于 fcntl( fd, F_DUPFD, 0) 2. 文件共享情况下的两个文件表项是存放在两个不同的进程中的。
阅读全文
摘要:前言 当打开一个文件的时候,我们需要指定打开文件的模式( 只读,只写等 )。那么在程序中如何获取,修改这个文件的状态标志呢?本文将告诉你如何用 fcntl函数 获取指定文件的状态标志。解决思路 1. 对于获取文件状态标志,我们可以通过调用fcntl函数得到一个记录文件标志的整型变量,然后分别让它和各个状态标志常量进行&操作。若操作结果为正则文件具有此状态标志,否则文件没有此状态标志。( 如果是检查只读,只写,可读可写,则需要和ACCMODE相&,然后判断其结果是否为O_RDONLY,O_WRONLY,O_RDWR )。 2. 对于增加文件状态标志,我们可以先调用fcntl函数得
阅读全文
摘要:前言 假如要你写一段代码创建一个文件( 如果文件已经存在则返回失败 )。你会怎么做?本文将讨论两种做法,并进行分析。错误代码示例 1 if ((fd = open(pathname, O_WRONLY)) < 0) { 2 if (errno == ENOENT) { 3 if ((fd = creat(pathname, mode)) < 0) 4 err_sys("creat error"); 5 } 6 else { 7 err_sys("open error"); 8 } 9 }10 ...
阅读全文