logo资料库

付晓帆--华科操作系统课设.doc

第1页 / 共16页
第2页 / 共16页
第3页 / 共16页
第4页 / 共16页
第5页 / 共16页
第6页 / 共16页
第7页 / 共16页
第8页 / 共16页
资料共16页,剩余部分请下载后查看
操作系统课程设计实验报告 专业:信息安全 班级:0903 姓名:付晓帆 学号:U200915328
一、 实验目的 掌握 Linux 操作系统的使用方法; 了解 Linux 系统内核代码结构; 掌握实例操作系统的实现方法。 二、 实验要求 1、 掌握 Linux 操作系统的使用方法,包括键盘命令、系统调用;掌握在 Linux 下的编程环境。  编一个 C 程序,其内容为实现文件拷贝的功能;  编一个 C 程序,其内容为分窗口同时显示三个并发进程的运行结 果。要求用到 Linux 下的图形库。 2、 掌握系统调用的实现过程,通过编译内核方法,增加一个新的系统调用。 另编写一个应用程序,调用新增加的系统调用。 实现的功能是:文件拷贝; 3、 掌握增加设备驱动程序的方法。通过模块方法,增加一个新的设备驱动 程序,其功能可以简单。 实现字符设备的驱动; 4、 了解和掌握/proc 文件系统的特点和使用方法  了解/proc 文件的特点和使用方法  监控系统状态,显示系统中若干部件使用情况  用图形界面实现系统监控状态。 5、 设计并实现一个模拟的文件系统(选作) 三、 实验一 1、 编一个 C 程序,其内容为实现文件拷贝的功能 要实现文件拷贝功能,主要用到的函数是 open、write、read。 以前在 windows 下写 C 语言打开文件常用的 fopen,此时不能用,因 为 fopen 是 ANSIC 标准中的 C 语言库函数,在不同的系统中应该调用不 同的内核 api ;所以应该直接使用 linux 中的系统函数 open。 主要用到的头文件: Unistd.h Fcntl.h Stdio.h sys/types.h \\此头文件包含适当时应使用的多个基本派生类型 \\包含了许多 Linux 系统服务的函数原型,如:read、write \\定义了很多宏和 open,fcntl 函数原型 \\标准输入输出头文件 sys/stat.h \\包含了获取文件属性的一些函数 errno.h string.h \\用于调试错误代码是所需要的一些 errno 变量 \\包含了处理字符串的一些函数 设计思路:由命令行参数获取 2 个文件名,根据其文件名和路 径分别打开该 2 个文件,设置一个循环,从源文件复制 N 个字节到
目的文件,直到源文件指针到文件尾,最后关闭 2 个文件。 在可能出错的地方需要加上相应的报错代码和中断,并输出错 误信息,以方便调试或是往后应用在第 2 小题中可能发生的错误。 理清楚设计思路后,根据需求写出相应的源代码见后页源程序代码 scopy.c ;在 Linux 终端使用编译命令 gcc –o scopy scopy.c 将程序编译并 生产 exe 可执行文件。 然后手动创建一个测试文件 test.txt ,在终端输入命令 ./scopy test.txt target.txt 这样就能将源文件 test.txt 复制到目标文件 target.txt 程序源代码 scopy.c: #include #include #include #include #include #include #include #define BUFFER_SIZE 1024 int main(int argc,char **argv) { int from_fd,to_fd; int bytes_read,bytes_write; char buffer[BUFFER_SIZE]; char *ptr; if(argc!=3) { //三个参数 //缓冲区大小 //设定一个缓冲区 fprintf(stderr,"Usage:%s fromfile tofile\n\a",argv[0]); return(-1); } /* 打开源文件 */ if((from_fd=open(argv[1],O_RDONLY))==-1) { fprintf(stderr,"Open %s Error:%s\n",argv[1],strerror(errno)); return(-1); } /* 创建目的文件 */ if((to_fd=open(argv[2],O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR))==-1) fprintf(stderr,"Open %s Error:%s\n",argv[2],strerror(errno)); return(-1); { }
while(bytes_read=read(from_fd,buffer,BUFFER_SIZE)) { /* 出错*/ if((bytes_read==-1)&&(errno!=EINTR)) break; else if(bytes_read>0) { ptr=buffer; while(bytes_write=write(to_fd,ptr,bytes_read)) { /* 出错*/ if((bytes_write==-1)&&(errno!=EINTR))break; /* 写完了所有读的字节 */ else if(bytes_write==bytes_read) break; /* 只写了一部分,继续写 */ else if(bytes_write>0) { } ptr+=bytes_write; bytes_read-=bytes_write; } /* 写的时候出错*/ if(bytes_write==-1)break; } } close(from_fd); close(to_fd); return(1); } 求用到 Linux 下的图形库。 安装 Linux 下的 GTK+: 2、 编一个 C 程序,其内容为分窗口同时显示三个并发进程的运行结果。要 首先要在 Linux 下载 GTK+相关库文件并安装。 在终端输入 sudo apt-get install gnome-core-devel ,然后根据提示操作, 就会安装 libgtk2.0-dev libglib2.0-dev 等开发所需的相关库文件。 $sudo apt-get install build-essential $sudo apt-get install gnome-core-devel $sudo apt-get install pkg-config $sudo apt-get install libgtk2.0*
编译 GTK+代码时需要包含的头文件是 gtk/gtk.h,此外,还必须连接 若干库;比如编译 test.c 时用以下命令。 gcc –o test test.c `pkg-config --cflags --libs gtk+-2.0` 在编写代码时需要用到的控件、窗口等视窗物件形态,用类 GtkWidget 定义其为指针类型。 编写一个 GTK+程序的基本步骤如下:  初始化 Gtk  建立控件  登记消息与消息处理函数  执行消息循环函数 gtk_main() 之后所设计的 3 个进程,基本上都是以这样的方式编写代码的,因为 之前曾用过 OpenGL,所以在这方面掌握的比较快。 初始化主要使用的函数有 gtk_init(&argc,&argv); gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(window),"标题名"); //设置窗口标 //启动 GTK //创建窗口 题名 gtk_widget_set_usize(window, 200, 200); gtk_widget_show(window); //设置窗口大小 //显示窗口 建立控件的一般流程 /*创建表格准备封装*/ gtk_table_new ( gint rows, gint columns, //创建多少列 //创建多少栏 //用来决定表格如何来定大小
gint homogeneous); /*这个函数是将表格 table,结合到窗口 window 里*/ gtk_container_add(GTK_CONTAINER(window),table); gtk_widget_show(table); // 显示该表格 /*要把物件放进 box 中,可用以下函数*/ void gtk_table_attach_defaults ( GtkTable*table, GtkWidget*widget, gintleft_attach, //参数("table")是选定某表格 //("child")是想放进去的物件 // 以 下 参数是指 定把物件 放在哪 里, 及用 多少个 boxes gintright_attach, ginttop_attach, gintbottom_attach); 实验截图: 实验源代码:process.c: #include #include #include gint progress_timeout( gpointer pbar ) { 0.01; if (new_val > 1.0) new_val = 0.0; gdouble new_val; char s[10]; new_val = gtk_progress_bar_get_fraction (GTK_PROGRESS_BAR (pbar)) +
sprintf (s, "%.0f%%", new_val*100); gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (pbar), new_val); gtk_progress_bar_set_text (GTK_PROGRESS_BAR (pbar),s); return TRUE; } void destroy_progress( GtkWidget *widget) { gtk_main_quit (); } void show(int argc,char *argv[],char *title ) { GtkWidget *window; GtkWidget *vbox; GtkWidget *pbar; GtkWidget *pbar2; GtkWidget *button; GtkWidget *label; int timer; char id_char[50]; gtk_init (&argc, &argv); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_resizable (GTK_WINDOW (window), TRUE); gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); g_signal_connect (destroy_progress), NULL); (G_OBJECT (window), "destroy", G_CALLBACK gtk_window_set_title (GTK_WINDOW (window), title); gtk_container_set_border_width (GTK_CONTAINER (window), 0); vbox = gtk_vbox_new (FALSE, 10); gtk_container_set_border_width (GTK_CONTAINER (vbox), 10); gtk_container_add (GTK_CONTAINER (window), vbox); gtk_widget_show (vbox);
sprintf (id_char, "本进程 ID:%d", getpid ()); label = gtk_label_new (id_char); gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); gtk_widget_show (label); sprintf (id_char, "父进程 ID:%d", getppid ()); label = gtk_label_new (id_char); gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); gtk_widget_show (label); pbar = gtk_progress_bar_new (); gtk_box_pack_start (GTK_BOX (vbox), pbar, FALSE, FALSE, 0); gtk_widget_show (pbar); timer = gtk_timeout_add (100, progress_timeout, pbar); button = gtk_button_new_with_label ("close"); g_signal_connect_swapped (G_OBJECT (button), "clicked", G_CALLBACK (gtk_widget_destroy), window); gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0); GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); gtk_widget_grab_default (button); gtk_widget_show (button); gtk_widget_show (window); gtk_main (); } int main(int argc, char *argv[]) { int pid = fork (); if (pid < 0) printf ("error!\n"); else if (pid == 0) { int pid = fork (); if (pid < 0) printf ("error!\n"); else if (pid == 0) show (argc,argv,"process3"); else show (argc,argv,"process2"); }
分享到:
收藏