Programming abstractions in C阅读笔记:p139-p143

《Programming Abstractions In C》学习第55天,p139-p140,总结如下:

一、技术总结

1.文件I/O操作

文件I/O操作可以分为一下这些步骤:

(1)声明文件指针对象。

File *infile;

(2)打开文件

fopen()。打开文件的模式有“r”, “w”, "a"三种模式。

(3)传输数据

读取文件的方式可以是character by character( getc()/putc() ),也可以是line by line( fget()/fput() )。

(4)关闭文件

fclose()。

2.文件I/O操作示例:复制文件

#include <stdio.h>
#include <stdbool.h> // for bool, true, false data type
#include <stdlib.h> // for exit()

void CopyRemovingComments(FILE *infile, FILE *outfile);

int main() {
    // 声明文件指针对象
    FILE *infile, *outfile;
    char *infileName, *outfileName;

    /*
     * 打开文件:fopen()
     * 如果文件不存在,则返回NULL,所以需要检查
     */
    infileName = "D:\\CProject\\chater3.4\\jabber.txt"; // 这里使用的是绝对路径,也可以使用相对路径
    outfileName = "D:\\CProject\\chater3.4\\jabbercopy.txt";
    infile = fopen(infileName, "r");
    if (infile == NULL) {
        printf("Cannot open input file: %s \n", infileName);
        exit(0);
    }

    /*
     * 传输数据
     * 传输数据有很多种方式,例如chracter by character(getc/putc),line by line(fget/fput, ReadLine)
     * 为了解决stdio.h存在的一些问题,作者对stdio进行了封装,封装后得到的的是simpio
     */
    outfile = fopen(outfileName, "w");
    if (outfile == NULL) {
        printf("Cannot open output file: %s \n", outfileName);
        exit(0);
    }

    CopyRemovingComments(infile, outfile);

    /*
     * 关闭文件
     */
    fclose(infile);
    fclose(outfile);
    printf("Copying is completed");

    return 0;
}

void CopyRemovingComments(FILE *infile, FILE *outfile) {
    int ch, nch;
    bool commentFlag; // 这里使用的是stdbool.h接口中的bool

    commentFlag = false; // 这里使用的是stdbool.h接口中的false,书中使用的是封装后的FALSE

    while ((ch = getc(infile)) != EOF) {
        if (commentFlag) {
            if (ch == '*') {
                nch = getc(infile); //
                if (nch == '/') {
                    commentFlag = false;
                } else {
                    ungetc(nch, infile);
                }
            }
        } else {
            if (ch == '/') {
                nch = getc(infile);
                if (nch == '*') {
                    commentFlag = true;
                } else {
                    ungetc(nch, infile);
                }
            }
            if (!commentFlag) {
                putc(ch, outfile);
            }
        }
    }
}

二、英语总结

1.endpoint什么意思?

答:c.the end of sth(终点)。

2.transfer什么意思?

答:transfer也是一个在计算机相关资料中经常看到的词。p140, For an input file, the function read data from the file into your program; for an output file, the function transfer data from the program to the file。数据从文件到程序中,或者从程序中到文件,即是一种transfer。通过该例句,对tranfer有一个形象的了解。

3.intermix什么意思?

答:

(1)解释:vi/vt. to combine two or more different things。

(2)搭配:intermix sth with sth。

(3)例句:p140, Doing so allows you to intermix numeric data with strings and other data types。

三、参考资料

1. 编程

(1)Eric S.Roberts,《Programming Abstractions in C》:https://book.douban.com/subject/2003414

2. 英语

(1)Etymology Dictionary:https://www.etymonline.com

(2) Cambridage Dictionary:https://dictionary.cambridge.org

欢迎搜索及关注:编程人(a_codists)

root@ecm-e00f:/# systemctl status apparmor × apparmor.service - Load AppArmor profiles Loaded: loaded (/lib/systemd/system/apparmor.service; disabled; preset: enabled) Active: failed (Result: exit-code) since Wed 2025-06-25 17:05:34 CST; 45s ago Docs: man:apparmor(7) https://gitlab.com/apparmor/apparmor/wikis/home/ Process: 338199 ExecStart=/lib/apparmor/apparmor.systemd reload (code=exited, status=1/FAILURE) Main PID: 338199 (code=exited, status=1/FAILURE) CPU: 39ms Jun 25 17:05:34 ecm-e00f apparmor.systemd[338206]: AppArmor parser error for /etc/apparmor.d in profile /etc/ap> Jun 25 17:05:34 ecm-e00f apparmor.systemd[338208]: AppArmor parser error for /etc/apparmor.d in profile /etc/ap> Jun 25 17:05:34 ecm-e00f apparmor.systemd[338228]: AppArmor parser error for /etc/apparmor.d/lsb_release in pro> Jun 25 17:05:34 ecm-e00f apparmor.systemd[338232]: AppArmor parser error for /etc/apparmor.d/nvidia_modprobe in> Jun 25 17:05:34 ecm-e00f apparmor.systemd[338236]: AppArmor parser error for /etc/apparmor.d/sbin.dhclient in p> Jun 25 17:05:34 ecm-e00f apparmor.systemd[338242]: AppArmor parser error for /etc/apparmor.d/usr.bin.man in pro> Jun 25 17:05:34 ecm-e00f apparmor.systemd[338199]: Error: At least one profile failed to load Jun 25 17:05:34 ecm-e00f systemd[1]: apparmor.service: Main process exited, code=exited, status=1/FAILURE Jun 25 17:05:34 ecm-e00f systemd[1]: apparmor.service: Failed with result 'exit-code'. Jun 25 17:05:34 ecm-e00f systemd[1]: Failed to start apparmor.service - Load AppArmor profiles.
06-26
<think>我们正在处理AppArmor加载配置文件失败的问题,错误信息提示解析错误(parsererrors)。根据引用[1],我们可以检查AppArmor的状态和已加载的配置文件。引用[2][3]提到了与Python模块相关的错误,但我们的问题更可能是配置文件语法错误。引用[4]提到了pyflakes,这是一个Python代码检查工具,但可能与配置文件语法检查无关。引用[5]是关于硬件操作的,不相关。解决步骤:1.**检查AppArmor状态**:使用`sudoaa-status`查看当前状态,但问题可能出现在启动时加载配置文件失败。2.**检查日志**:使用`journalctl-uapparmor-xe`查看详细错误日志,定位具体是哪个配置文件出错。3.**测试所有配置文件语法**:使用`apparmor_parser`工具检查配置文件的语法:```bashsudoapparmor_parser-QT/etc/apparmor.d/*```这将测试所有配置文件的语法,并报告错误位置。4.**修复或禁用错误配置文件**:-如果发现具体哪个文件出错,可以尝试修复该文件(根据错误信息调整语法)。-如果暂时无法修复,可以移动该文件到备份目录(如`/etc/apparmor.d/disable/`),然后重新加载AppArmor:```bashsudomv/etc/apparmor.d/problem_profile/etc/apparmor.d/disable/sudosystemctlrestartapparmor```5.**重新加载配置文件**:修复后,重新加载配置文件:```bashsudosystemctlreloadapparmor```6.**验证**:再次检查状态和日志:```bashsudoaa-statussystemctlstatusapparmor```**注意**:如果多个文件出错,可能需要逐个修复。常见错误包括语法错误(如缺少括号、错误的规则格式)或包含不存在的文件。如果问题涉及Python模块(如引用[2][3]中的错误),可能是`aa-genprof`等工具的问题,但这不影响AppArmor服务本身。但若配置文件是由这些工具生成且包含错误,则仍需修复配置文件。**引用标识**:在回答中引用相关段落时,在末尾添加引用标识,例如:AppArmor配置文件存储在`/etc/apparmor.d/`目录下[^1]。生成相关问题:1.如何调试AppArmor配置文件语法错误?2.AppArmor服务启动失败的其他常见原因有哪些?3.如何临时禁用AppArmor配置文件?根据以上思路,编写回答。</think>### 解决 AppArmor 配置文件加载失败问题(Parser Errors) 当 AppArmor 服务因配置文件解析错误而启动失败时,根本原因是配置文件存在语法或结构问题。以下是系统化的解决步骤: #### 步骤 1:定位错误配置文件 ```bash sudo journalctl -u apparmor -xe --since "1 hour ago" | grep "AppArmor parser error" ``` 检查输出中明确指出的错误文件和行号,例如: ``` Profile /etc/apparmor.d/usr.sbin.mysqld failed to load: Syntax error at line 15 ``` #### 步骤 2:批量检查配置文件语法 ```bash # 测试所有配置文件的语法(-Q=安静模式,-T=显示错误) sudo apparmor_parser -QT /etc/apparmor.d/* ``` 输出示例: ``` Error: Could not open 'abstractions/missing_file' (No such file or directory) in profile /etc/apparmor.d/nginx Syntax error at line 22 in /etc/apparmor.d/custom_profile ``` #### 步骤 3:修复常见错误类型 | 错误类型 | 修复方法 | 示例 | |---------|----------|------| | **包含文件缺失** | 创建缺失文件或注释包含行 | `sudo touch /etc/apparmor.d/abstractions/missing_file` | | **语法错误** | 按规范修正规则 | 错误:`/data/** rw,` → 修正:`/data/** rw,` | | **规则冲突** | 删除重复规则 | 删除重复的 `capability net_bind_service` | | **路径错误** | 验证路径是否存在 | `/var/run/nonexist.sock` → 改为实际路径 | #### 步骤 4:临时禁用问题配置(紧急恢复) ```bash # 移动错误配置文件到隔离目录 sudo mkdir -p /etc/apparmor.d/disable/ sudo mv /etc/apparmor.d/faulty_profile /etc/apparmor.d/disable/ # 重新加载服务 sudo systemctl restart apparmor ``` #### 步骤 5:深度修复配置文件 1. **使用调试模式**: ```bash sudo apparmor_parser -d -T /etc/apparmor.d/problem_profile ``` 2. **检查依赖抽象层**: ```bash grep 'include' /etc/apparmor.d/problem_profile | while read line; do echo "Checking: ${line#include <}"; ls "/etc/apparmor.d/${line#include <}" done ``` 3. **重建配置文件**(参考引用[2]): ```bash sudo aa-genprof /path/to/application # 需要安装apparmor-utils ``` #### 步骤 6:验证修复结果 ```bash # 检查服务状态 sudo systemctl status apparmor # 确认配置文件加载 sudo aa-status | grep "profiles are loaded" ``` 成功输出应显示: ``` 15 profiles are loaded. ``` > **重要提示**:操作前备份配置: > ```bash > sudo cp -a /etc/apparmor.d{,.bak_$(date +%F)} > ``` ### 常见错误原因 1. **手动编辑错误**:直接修改配置文件导致语法错误 2. **抽象层缺失**:`#include <abstractions/...>` 指向不存在的文件[^1] 3. **工具链问题**:`aa-genprof` 因 Python 模块缺失生成错误配置(引用[2][3]) 4. **版本不兼容**:旧版配置文件在新版 AppArmor 中失效
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值