写在前面 shell作为一种与内核对话的一种方式,为我们使用操作系统服务,提供了很多便利。在我们使用Linux时,shell是不得不接触的内容之一。为了学习和熟悉Linux进程相关的内核函数,我们可以尝试着自己实现一个shell。 源代码 src/Makefile SOURCES = $(wildcard *.cpp) OBJECTS = $(patsubst %.cpp, %.o, $(SOURCES)) CXXFLAG = -std=c++14 -I ../include -O2 -lreadline psh: $(OBJECTS) g++ $(CXXFLAG) -o psh $(OBJECTS) $(OBJECTS): $(SOURCES) g++ $(CXXFLAG) -c $(SOURCES) .PHONY: clean clean : -rm $(OBJECTS) include/psh.h #pragma once #ifndef 继续阅读 >>


娄泽豪 17/07/25 09:13:02
进程标识符 函数原型及解释 pid_t getpid(void); pid_t getppid(void); uid_t getuid(void); uid_t geteuid(void); gid_t getgid(void); gid_t getegid(void); 返回值:成功时getpid返回自身的pid,getppid返回自身父进程的pid,getuid返回自身的实际运行uid,geteuid返回自身的有效运行uid,getgid返回自身实际运行gid,getegid返回自身有效运行gid。这些函数均没有出错返回。 创建子进程 函数原型及解释 pid_t fork(void); pid_t vfork(void); 返回值:若函数执行失败,则返回-1,若函数执行成功,由于产生了子进程,因此函数将有两个返回值。在父进程中,函数将返回子进程的pid,在子进程中,函数将返回0。 其他相关解释 返回值为何如此设计:一个父进程可以有多个子进程,因此f 继续阅读 >>


娄泽豪 17/07/24 14:48:43
随便扯点什么 实际上刚开始让我实现ls(1)我是拒绝的,因为,你不能让我写,我就马上去写,第一我要看一下,因为我不愿意写完了以后再加一些特技上去,比如ls忽然“Segmentation Fault”了,很懵逼、很低能,这样用过ls的人出来一定会骂我,根本没有这样辣鸡的ls,就证明这ls一点也不好用,就是在骗人。后来组长告诉我只用实现-a -l -R就好,我写了两天左右,感觉还不错,后来我在使用的时候就没有加特技,就很舒服。 源代码 src/Makefile SOURCES = $(wildcard *.cpp) OBJECTS = $(patsubst %.cpp, %.o, $(SOURCES)) CXXFLAG = -std=c++14 -I ../include -Wall -O2 pls: $(OBJECTS) g++ $(CXXFLAG) -o pls $(OBJECTS) $(OBJECTS): $(SOURCES) g++ $(CXXFLAG) -c *.cpp 继续阅读 >>


娄泽豪 17/07/23 22:28:19
获得文件属性 函数功能:获得文件的属性。 函数原型及解释 int stat(const char *restrict path, struct stat *restrict buf); int fstat(int fildes, struct *buf); int lstat(const char *restrict path, struct stat *restrict buf); 返回值:若执行成功则返回0,失败则返回-1。 path:要获得文件属性的文件的路径。既可以是绝对路径也可以是相对路径。 fildes:要控制的文件描述符。 buf:获得的文件属性将存在buf参数所指的内存中。 设置文件的归属 函数功能:设置文件所属的用户和用户组。 函数原型及解释 int chown(const char *path, uid_t owner, gid_t group); int fchown(int fildes, uid_t owner, gid_t group); in 继续阅读 >>


娄泽豪 17/07/20 17:19:30
POSIX 错误处理 POSIX函数若执行时发生错误,大部分函数都将设置全局变量errno,以下内容若未特别提及,均在执行失败时设置了errno。 各个errno变量可以取的常数值可以使用man 3 errno查看man手册得知。 打开文件 函数功能: 打开文件并返回文件描述符,其他功能视参数而定。 函数原型及解释 int open(const char *path, int oflag, ...); //一般使用的两种形式: int open(const char *path, int oflag); int open(const char *path, int oflag, mode_t mode); 返回值:若执行成功则返回该文件描述符,失败则返回-1。 path:要打开的文件位置,既可以是绝对路径也可以是相对路径。 oflag:打开文件的方式。 mode:仅当oflag设置了O_CREAT时有效,要创建的文件的权限。 参数 其中参数oflag可选项有: 继续阅读 >>


娄泽豪 17/07/20 11:43:42
题目十一 以下程序段的运行结果是什么? #include<stdio.h> int main(int argc, char *argv[]) { int nums[5] = {2, 4, 6, 8, 10}; int *ptr = (int *)(&nums + 1); printf("%d, %d\n", *(nums + 1), *(ptr - 1)); return 0; } 为了一探究竟机器到底在执行该段程序做了什么,可以阅读该段代码对应的汇编指令,使用gcc -S指令(这里使用的gcc版本为7.1.1),可以生成类似于以下的汇编代码: ; 代码中略去了一些伪指令 .LC0: .string "%d,%d\n" .text main: .LFB0: pushq %rbp ;将被调者保存信息压入栈 movq %rsp, %rbp ;将当前栈顶 继续阅读 >>


娄泽豪 17/06/27 17:58:49
配置源 在ArchlinuxCN源中有很多方便中国用户使用的包,其中也包含了经常使用的搜狗拼音输入法,于是我们需要先配置ArchlinuxCN源,这样我们就可以使用自带的包管理器Pacman直接安装搜狗拼音输入法。 首先使用文本编辑器打开/etc/pacman.conf,末尾增加以下两句: [archlinuxcn] Server = https://mirrors.ustc.edu.cn/archlinuxcn/$arch 然后我们更新一下软件仓库: sudo pacman -Sy 这里我们就完成了添加源的操作。 安装 安装Fcitx 由于搜狗拼音输入法依赖于Fcitx,在安装搜狗拼音输入法之前,需要先行安装Fcitx,在终端窗口下直接输入: sudo pacman -S fcitx 即可完成安装,需要注意的是,仅仅安装这一项是不够的,这样在安装完成之后,Fcitx基本上是处于不可用的状态,我们还需要安装以下几个包: sudo pacman -S fcitx-confi 继续阅读 >>


娄泽豪 17/06/26 11:33:56
特别约定 在以下所有叙述中,C-× 都代表同时按住Ctrl和×键,M-×都代表同时按住Alt和×键。 屏幕移动 向下滚动一屏 C-v 向上滚动一屏 M-v 重新定位光标相对于屏幕所在的位置 C-l 光标控制 向上移动一行 C-p 向下移动一行 C-n 向左移动一个字符 C-b 向左移动一个单词 M-b 向右移动一个字符 C-f 向右移动一个单词 M-f 移动到一行的最前 C-a 移动到一句的最前 M-a 移动到一行的末尾 C-e 移动到一句的末尾 M-e 移动到文件的最前 M-< 移动到文件的末尾 M-> 重复操作n次 C-u n [操作快捷键], 如向下移动3行,C-u 3 C-n 操作控制 强制取消当前操作 C-g 保存当前文件 C-x C-s 打开/创建文件 C-x C-f 退出Emacs C-x C-v 分屏/多文件 关闭其他屏幕 C-x 1 上下分割当前屏幕 C-x 2 左右分割当前屏幕 C-x 3 切换当前屏幕 C-x o 切换当前屏幕Buff 继续阅读 >>


娄泽豪 17/06/19 22:55:17
Problem A: 加法变乘法 Time Limit: 10 Sec Memory Limit: 256 MB Description 已知X可以写成从1开始连续若干个整数的和, 现在要求把其中两个不相邻的加号变成乘号,使得结果为Y。 找出所有满足条件的可能答案并输出(把两个乘号左边的数字用小括号括起来,中间用英文逗号间隔,两个括号之间不空格); 若找不到满足的条件,则输出“NONE”字样。编写程序,完成n组数据的判定。 例如:当X为1225,Y为2015时 因为:1+2+3+ ... + 49 = 1225 且1+2+3+...+10*11+12+...+27*28+29+...+49 = 2015 所以:一个解为(10,27)。 Input 第一行为n值,接下来依次n行的第一个数据是加法结果X,第二个数据是变乘法后的结果Y,以空格间隔。 Output 输出n行,每一行的格式为“(***,***)(***,***)”(或者“NONE”)。请严格按照 格式书写,不能出现其它文字或符号 继续阅读 >>


娄泽豪 17/06/18 14:28:43
伪代码 BFS(G, s): for each vertex u ∈ G.V - {s}: u.color = White u.d = ∞ u.π = NIL s.color = Gray s.d = 0 s.π = NIL Q = ∅ Q.push(s) while Q ≠ ∅: u = Q.pop() for each v ∈ G.Adj[u]: if v.color == White then v.color = Gray v.d = u.d + 1 v.π = u Q.push(v) u.color = Black C++的一般实现方式 第一种写法 首先,我们严格按照伪代码形式来将之写为C++形式。 第一步就是先构造每一个结点,因 继续阅读 >>


娄泽豪 17/06/02 20:31:56