2017-2018-1 20155330 《信息安全系统设计基础》第10周课堂测试&课下作业
stat命令的实现-mysate
- 学习使用stat(1),并用C语言实现
- 提交学习stat(1)的截图
- man -k ,grep -r的使用
- 伪代码
- 产品代码 mystate.c,提交码云链接
- 测试代码,mystat 与stat(1)对比,提交截图
STAT(1)学习
- 使用
man 1 stat
命令查看
- 使用
man -k stat | grep 2
查找相关函数
man 2 stat
查看stat函数
- 产品代码
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
struct stat sb;
if (argc != 2) {
fprintf(stderr, "Usage: %s <pathname>\\n", argv[0]);
exit(EXIT_FAILURE);
}
if (stat(argv[1], &sb) == -1) {
perror("stat");
exit(EXIT_FAILURE);
}
printf("File type: ");
switch (sb.st_mode & S_IFMT) {
case S_IFBLK: printf("block device\\n"); break;
case S_IFCHR: printf("character device\\n"); break;
case S_IFDIR: printf("directory\\n"); break;
case S_IFIFO: printf("FIFO/pipe\\n"); break;
case S_IFLNK: printf("symlink\\n"); break;
case S_IFREG: printf("regular file\\n"); break;
case S_IFSOCK: printf("socket\\n"); break;
default: printf("unknown?\\n"); break;
}
printf("I-node number: %ld\\n", (long) sb.st_ino);
printf("Mode: %lo (octal)\\n",
(unsigned long) sb.st_mode);
printf("Link count: %ld\\n", (long) sb.st_nlink);
printf("Ownership: UID=%ld GID=%ld\\n",
(long) sb.st_uid, (long) sb.st_gid);
printf("Preferred I/O block size: %ld bytes\\n",
(long) sb.st_blksize);
printf("File size: %lld bytes\\n",
(long long) sb.st_size);
printf("Blocks allocated: %lld\\n",
(long long) sb.st_blocks);
printf("Last status change: %s", ctime(&sb.st_ctime));
printf("Last file access: %s", ctime(&sb.st_atime));
printf("Last file modification: %s", ctime(&sb.st_mtime));
exit(EXIT_SUCCESS);
}
- 实现mystat.c,与stat命令比对如图
程序运行
- 理解test.c, 说出程序功能
- 编译运行程序,提交运行截图
TEST
- test.c代码
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
main()
{
int fd;
int newfd;
char line[100];
fgets(line,100,stdin);
printf("%s",line);
fgets(line,100,stdin);
printf("%s",line);
fgets(line,100,stdin);
printf("%s",line);
fd=open("data",O_RDONLY);
newfd=dup2(fd,0);
if(newfd!=0)
{
fprintf("stderr","Could not duplicate fd to 0\\n");
exit(1);
}
close(fd);
fgets(line,100,stdin);
printf("%s",line);
fgets(line,100,stdin);
printf("%s",line);
fgets(line,100,stdin);
printf("%s",line);
}
- data文件内容
20155330
hello
world
-
*test.c功能:从文件描述符读取数据,将标准输入定向到文件。
- 初始状态:系统中采用的是典型的设置---三种标准流被连接到终端设备上:输入的数据流经过文件描述符0,输出的标准流经过文件描述符1,2。
- 其次:关闭(0)即将标准输入的连接挂断则当前文件描述符数组的第一个元素现在处于空闲状态。
- 最后:使用开放(文件名,O_RDONLY)打开一个想连到标准输入上的文件根据最低可用描述符原则,打开的文件被连接到标准输入上。
-
运行截图
课下作业——IPC
研究Linux下IPC机制:原理,优缺点,每种机制至少给一个示例,提交研究博客的链接
共享内存
- 采用共享内存通信的一个显而易见的好处是效率高,因为进程可以直接读写内存,而不需要任何数据的拷贝。对于像管道和消息队列等通信方式,则需要在内核和用户空间进行四次的数据拷贝,而共享内存则只拷贝两次数据[1]:一次从输入文件到共享内存区,另一次从共享内存区到输出文件。实际上,进程之间在共享内存时,并不总是读写少量数据后就解除映射,有新的通信时,再重新建立共享内存区域。而是保持共享区域,直到通信完毕为止,这样,数据内容一直保存在共享内存中,并没有写回文件。共享内存中的内容往往是在解除映射时才写回文件的。因此,采用共享内存的通信方式效率是非常高的。
- 示例
管道
- 管道是Linux支持的最初Unix IPC形式之一,具有以下特点:
- 管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道;
- 只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程);
- 单独构成一种独立的文件系统:管道对于管道两端的进程而言,就是一个文件,但它不是普通的文件,它不属于某种文件系统,而是自立门户,单独构成一种文件系统,并且只存在与内存中。
- 数据的读出和写入:一个进程向管道中写的内容被管道另一端的进程读出。写入的内容每次都添加在管道缓冲区的末尾,并且每次都是从缓冲区的头部读出数据。
- 缺点:管道只能在本地计算机中使用,而不可用于网络间的通信。
- 示例
FIFO
- 管道应用的一个重大限制是它没有名字,因此,只能用于具有亲缘关系的进程间通信,在有名管道(named pipe或FIFO)提出后,该限制得到了克服。FIFO不同于管道之处在于它提供一个路径名与之关联,以FIFO的文件形式存在于文件系统中。这样,即使与FIFO的创建进程不存在亲缘关系的进程,只要可以访问该路径,就能够彼此通过FIFO相互通信(能够访问该路径的进程以及FIFO的创建进程之间),因此,通过FIFO不相关的进程也能交换数据。值得注意的是,FIFO严格遵循先进先出(first in first out),对管道及FIFO的读总是从开始处返回数据,对它们的写则把数据添加到末尾。它们不支持诸如lseek()等文件定位操作。
- 示例
信号
- 信号是在软件层次上对中断机制的一种模拟,在原理上,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的。信号是异步的,一个进程不必通过任何操作来等待信号的到达,事实上,进程也不知道信号到底什么时候到达。
- 信号是进程间通信机制中唯一的异步通信机制,可以看作是异步通知,通知接收信号的进程有哪些事情发生了。信号机制经过POSIX实时扩展后,功能更加强大,除了基本通知功能外,还可以传递附加信息。
- 信号事件的发生有两个来源:硬件来源(比如我们按下了键盘或者其它硬件故障);软件来源,最常用发送信号的系统函数是kill, raise, alarm和setitimer以及sigqueue函数,软件来源还包括一些非法运算等操作。
- 示例:信号阻塞及信号集操作。
消息队列
- 系统V消息队列是随内核持续的,只有在内核重起或者显示删除一个消息队列时,该消息队列才会真正被删除。因此系统中记录消息队列的数据结构(struct ipc_ids msg_ids)位于内核中,系统中的所有消息队列都可以在结构msg_ids中找到访问入口。
- 消息队列就是一个消息的链表。每个消息队列都有一个队列头,用结构struct msg_queue来描述。队列头中包含了该消息队列的大量信息,包括消息队列键值、用户ID、组ID、消息队列中消息数目等等,甚至记录了最近对消息队列读写进程的ID。读者可以访问这些信息,也可以设置其中的某些信息。
- 示例