先安装ccache能够大幅节省屡次内核编译时间linux
vim ./arch/x86/entry/syscalls/syscall_64.tbl 尾部添加 ([549]为最后一个系统调用号+1) 549 64 mysetnice sys_mysetnice
vim ./include/linux/syscalls.h asmlinkage long sys_mysetnice(pid_t pid,int flag,int nicevalue); //,void __user* prio,void __user* nice);
vim ./kernel/sys.c SYSCALL_DEFINE3(mysetnice, pid_t, pid, int, flag, int, nicevalue) { struct pid * kpid; struct task_struct * task; int nicebef; kpid = find_get_pid(pid);/* 返回pid */ task = pid_task(kpid, PIDTYPE_PID);/* 返回task_struct */ nicebef = task_nice(task);/* 返回进程当前nice值 */ if(flag == 1) { set_user_nice(task, nicevalue);/* 修改进程nice值 */ printk("修改前nice值:%d\t修改后nice值:%d\n", nicebef, nicevalue); return 0; } else if(flag == 0) { printk("该进程的nice值为%d\n", nicebef); return 0; } return EFAULT; }
make oldconfig make make modules make modules_install make install grub2-mkconfig -o /boot/grub2/grub.cfg //centos update-grub2 //ubuntu reboot
#include <linux/unistd.h> #include <sys/syscall.h> #include <stdio.h> #include <stdlib.h> #define __NR_mysetnice 549 int main(int argc, char *argv[]) { pid_t tid; int nicevalue = atoi(argv[1]); tid = getpid(); syscall(__NR_mysetnice,tid,0,0); syscall(__NR_mysetnice,tid,1,nicevalue); syscall(__NR_mysetnice,tid,0,0); //syscall(__NR_mysetnice,tid,flag,nicevalue); return 0; }
dmesg
Makefile的KDIR须要修改成内核目录 Makefile 和 OS-2-x.c在同一文件夹内便可 执行make编译web
obj-m:=OS-2-1.o OS21-objs:=OS-2-1.o KDIR:=/home/kannaduki/linux/linux-4.15.15 PWD:= $(shell pwd) default: make -C $(KDIR) M=$(PWD) modules clean: make -C $(KDIR) M=$(PWD) clean
#include<linux/init.h> #include<linux/module.h> #include<linux/kernel.h> // 内核版本为3.X 则为<linux/sched.h> #include<linux/sched/signal.h> static int hello_init(void) { struct task_struct *p= &init_task; printk(KERN_ALERT"\n\n\n----------------------"); printk(KERN_ALERT"------全部进程程序名 pid 进程状态 父进程------"); for_each_process(p) { if(p->mm == NULL) printk(KERN_ALERT"程序名: %s Pid: %d 进程状态: %ld 父进程pid: %d\n",p->comm,p->pid, p->state,p->real_parent->pid); } printk(KERN_ALERT"----------------------\n\n\n"); return 0; } static void hello_exit(void) { printk(KERN_ALERT "______Exit______ !\n"); } module_init(hello_init); module_exit(hello_exit); MODULE_LICENSE("GPL");
obj-m:=OS-2-2.o OS22-objs:=OS-2-2.o KDIR:=/home/kannaduki/linux/linux-4.15.15 PWD:= $(shell pwd) default: make -C $(KDIR) M=$(PWD) modules clean: make -C $(KDIR) M=$(PWD) clean
#include<linux/init.h> #include<linux/module.h> #include<linux/kernel.h> #include<linux/pid.h> // 内核版本为3.X 则为<linux/sched.h> #include <linux/sched/signal.h> #include <linux/moduleparam.h> static pid_t pid=0; module_param(pid,int,0644); static int family_init(void) { struct task_struct *p; struct list_head *pp; struct task_struct *pl; if(pid == 0) { printk("输入错误\n"); return 0; } p = pid_task(find_vpid(pid), PIDTYPE_PID); if(!p) { printk("\n\n\n------进程不存在----\n\n\n"); return 0; } printk("\n\n\n\n\n\n\n\n\n"); printk("-----进程号------\n"); printk("%d\n",pid); printk("-----父进程------\n"); if(p->parent==NULL) { printk("父进程不存在\n"); } else { printk("pid: %d 程序名:%s 进程状态: %ld\n",p->parent->pid,p->parent->comm,p->parent->state); } printk("------兄弟进程-------\n"); list_for_each(pp,&p->parent->children) { pl=list_entry(pp,struct task_struct,sibling); printk("pid: %d 程序名: %s 进程状态: %ld\n",pl->pid,pl->comm,pl->state); } printk("---------子进程--------\n"); if(&p->children==NULL) printk("子进程不存在"); list_for_each(pp,&p->children) { pl=list_entry(pp,struct task_struct,sibling); printk("pid: %d 程序名: %s 进程状态: %ld\n",pl->pid,pl->comm,pl->state); } printk("-----------------------\n\n\n\n\n\n"); return 0; } static void family_exit(void) { printk(KERN_ALERT "\n--------Exit---------\n"); } module_init(family_init); module_exit(family_exit); MODULE_LICENSE("GPL");
#include<stdio.h> void main() { printf("cmd1运行完毕\n"); }
gcc cmd1.c -o cmd1 (cmd2 cmd3 同理)
shell
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> void main() { int pid; int i; char *cmd = (char*)malloc(sizeof(20)); while(1) { printf("输入指令\n"); scanf("%s",cmd); if(strcmp(cmd,"exit")==0) return; pid=vfork(); if (pid) { waitpid(pid,NULL,0); }else{ if(strcmp(cmd,"cmd1")==0 || strcmp(cmd,"cmd2")==0 || strcmp(cmd,"cmd3")==0){ execl(cmd,cmd,NULL); }else{ printf("Command not found\n"); _exit(0); } } } }
gcc shell.c
编程
#include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <semaphore.h> #include <string.h> int main() { int filedes[2]; pid_t child1; pid_t child2; pid_t child3; char b_read[100]={0}; int num; sem_t sem; sem_init(&sem,1,1); //int pipe(int filedes[2]) if(pipe(filedes)<0) exit(-1); else { //close(filedes[0]); //close(filedes[1]); } //filedes[0]读 filedes[1]写 pid_t p1 = fork(); if(p1==0) { sem_wait(&sem); close(filedes[0]); open(filedes[1]); write(filedes[1],"1111",4); printf("child1 写入 写入值为1111\n\n"); close(filedes[1]); sem_post(&sem); exit(0); } pid_t p2 = fork(); if(p2==0) { sem_wait(&sem); close(filedes[0]); open(filedes[1]); write(filedes[1],"2222",4); printf("child2 写入 写入值为2222\n\n"); close(filedes[1]); sem_post(&sem); exit(0); } pid_t p3 = fork(); if(p3==0) { sem_wait(&sem); close(filedes[0]); open(filedes[1]); write(filedes[1],"3333",4); printf("child3 写入 写入值为3333\n\n"); close(filedes[1]); sem_post(&sem); exit(0); } int s1,s2,s3,n; //open(filedes[0]); close(filedes[1]); //waitpid(p1,&s1,0); //waitpid(p2,&s2,0); //waitpid(p3,&s3,0); usleep(400); printf("请输入读取数\n"); scanf("%d",&n); printf("读取%d\n\n",n); num = read(filedes[0],b_read,n); printf("返回值%d,读取值%s\n\n",num,b_read); close(filedes[0]); return 0; }
gcc OS-3-2.c -o OS-3-2 -pthread
ubuntu
#include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <semaphore.h> #include <string.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> // gcc OS-3-3.c -o OS-3-3 -pthread // ./OS-3-3 // 第三个题和第四个题跑多了好像ftok的key_t会混起来 接收不到信息 改一下或者重启一下就好了 sem_t sem; int sval; void sender() { sem_wait(&sem); key_t key; int msqid,msnd; char msgp[100] = {0}; key = ftok(".",1); msqid = msgget(key,IPC_CREAT); while(1) { printf("请输入消息\n"); scanf("%s",msgp); if(strcmp(msgp,"exit")==0){ strcpy(msgp,"end"); msnd = msgsnd(msqid,msgp,strlen(msgp),MSG_NOERROR); printf("--------------------------------\n"); printf("发送%d个字符(end),应答信息以下\n",strlen(msgp)); break; }else{ msnd = msgsnd(msqid,msgp,strlen(msgp),MSG_NOERROR); printf("发送%d个字符,输入exit应答\n",strlen(msgp)); } } //msnd = msgsnd(msqid,msgp,strlen(msgp),MSG_NOERROR); //printf("sender key_t: %d IPC:%d \n",key,msqid); sem_post(&sem); usleep(100); sem_wait(&sem); msgrcv(msqid,msgp,100,0,0); printf("sender 接收 %s\n",msgp); sem_post(&sem); } void receiver() { usleep(100); sem_wait(&sem); //printf("receiver start\n"); key_t key; int msqid; int count; ssize_t mrcv; struct msqid_ds *buf; char msgp[100]={0}; key = ftok(".",1); msqid = msgget(key,IPC_CREAT); count = 0; while(msgrcv(msqid,msgp,100,0,IPC_NOWAIT)!= -1) { count++; printf("第%d条信息 %s\n",count,msgp); } strcpy(msgp,"over"); msgsnd(msqid,msgp,strlen(msgp),MSG_NOERROR); printf("receiver 发送 over\n"); sem_post(&sem); usleep(100); if(msgctl(msqid,IPC_RMID,buf) == 0) printf("消息队列删除成功\n"); printf("-----------------------------\n"); } int main(void) { pthread_t tid1, tid2; sem_init(&sem, 0, 1); pthread_create(&tid1,NULL,sender,NULL); pthread_create(&tid2,NULL,receiver, NULL); pthread_join(tid1,NULL); pthread_join(tid2,NULL); sem_destroy(&sem); return 0; }
#include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <semaphore.h> #include <string.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <sys/shm.h> #include <fcntl.h> struct shm_msg { pid_t pid; char msg[100]; }; int main() { sem_t *sem; int shmid; char msg[100]; struct shm_msg *shmaddr; sem = sem_open("mysem",O_CREAT,0644,1); shmid = shmget(ftok(".",1),1024,IPC_CREAT); shmaddr = shmat(shmid,0,0); shmaddr->pid = -1; printf("请输入字符串\n"); scanf("%s",msg); sem_wait(sem); shmaddr->pid = 1; strcpy(shmaddr->msg,msg); printf("sender 发送 %s\n",shmaddr->msg); sem_post(sem); while(1) { if(shmaddr->pid == 0){ sem_wait(sem); printf("sender 接收 %s",shmaddr->msg); break; } } sem_post(sem); sem_close(sem); sem_unlink("mysem"); return 0; }
#include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <semaphore.h> #include <string.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <sys/shm.h> #include <fcntl.h> struct shm_msg { pid_t pid; char msg[100]; }; int main() { sem_t *sem; int shmid; char msg[100]; struct shm_msg *shmaddr; sem = sem_open("mysem",O_CREAT,0644,1); shmid = shmget(ftok(".",1),1024,IPC_CREAT); shmaddr = shmat(shmid,0,0); while(1) { if(shmaddr->pid == 1){ sem_wait(sem); printf("receiver 接收 %s\n",shmaddr->msg); strcpy(shmaddr->msg,"over"); printf("receiver 发送 %s \n",shmaddr->msg); shmaddr->pid = 0; break; } } sem_post(sem); sem_close(sem); return 0; }
打开两个终端 一个执行sender 一个执行receiver sender发送信息后receiver会接收
vim
#include<stdio.h> #include<stdlib.h> #include<time.h> #include<string.h> #define BLOCKSIZE 1024 #define SIZE 1024000 #define END 65535 #define FREE 0 #define MAXOPENFILE 10 #define CUVER 0 #define APPEND 1 #pragma warning(disable:4996) typedef struct BLOCK0 { char infomation[50]; //你想要提示的第一句话 unsigned short blocksize; //设成1024,单位B unsigned short totalsize; //设成1000,单位KB unsigned short fat_num; // fat表的数量,设成2 unsigned short root;// 根目录文件的起始盘块号 unsigned char *startblock; /*tsz:对free的管理须要完善*/ unsigned free_block; //剩余未使用的块数 }block0; typedef struct FCB { char filename[8]; //文件名 char exname[3]; //扩展名 unsigned char attribute; //属性,0目录;1文件 unsigned short time; unsigned short data; unsigned short first; unsigned long length; char free; //0为空,1相反 char reserved[7]; //预留,同时也为了内存对齐 }fcb; // /* 这个数据结构为长文件准备,以倒序顺序放在长文件FCB的前面*/ //typedef struct EXTEND_NAME{ // unsigned char endflag; /*若end是1则为最后一个EXTEND_NAME,不然为0*/ // char extname1[10]; /*扩展名的存储位置1*/ // unsigned char attribute; /*属性,长文件的扩展名的属性为4*/ // char extname2[20]; /*扩展名的存储位置2*/ //}ext_name; typedef struct FAT { unsigned short id; }fat; typedef struct USEROPEN { char filename[8]; char exname[4]; unsigned char attribute; unsigned short time; unsigned short data; unsigned short first; unsigned long length; char free; fcb *ptrfcb; //指向加载的fcb int count; //读写指针的位置 short fcbstate;// 是否修改了文件的FCB的内容,1:修改;0:未修改 short topenfile;// 户打开表项是否为空,0:空;1:已分配 }useropen; unsigned char *myvhard; //虚拟磁盘开始位置的指针 useropen openfilelist[MAXOPENFILE]; char currentdir[100]; unsigned char* startp; //磁盘数据区开始位置的指针 useropen *ptrcurdir;// 指向用户打开文件表中的当前目录所在打开文件表项的位置 fat *fat1; fat *fat2;
void info() { block0 *p = (block0*)myvhard; printf("*\t%s\n", p->infomation); printf("*\t块大小为:%dB,总大小为:%dKB\n", p->blocksize, p->totalsize); printf("*\tfat表数量为:%d\n", p->fat_num); printf("*\t数据区的开始块数为:%d\n", p->root); printf("*\t剩余未分配块数为:%d\n", p->free_block); } void help() { printf("*\t命令名称\t参数\t\t解释\n"); printf("*\tinfo\t\t无\t\t获取文件系统总体信息\n"); printf("*\thelp\t\t无\t\t获取全部命令的说明\n"); printf("*\tcd\t\tdirname\t\t改变当前目录到指定的名为 dirname 的目录\n"); printf("*\topen\t\tfilename\t打开当前目录下名为 filename 的文件\n"); printf("*\tformat\t\t无\t\t对虚拟磁盘进行格式化,布局虚拟磁盘,创建根目录文件(或根目录区)\n"); printf("*\tmkdir\t\tdirname\t\t在当前目录下建立名为 dirname 的子目录\n"); printf("*\trmdir\t\tdirname\t\t在当前目录下删除名为 dirname 的子目录\n"); printf("*\tls\t\t无\t\t显示当前目录的内容(子目录和文件信息)\n"); printf("*\tcreate\t\tfilename\t建立名为 filename 的新文件\n"); printf("*\tclose\t\tfd\t\t关闭前面由 my_open 打开的文件描述符为 fd 的文件\n"); printf("*\twrite\t\tfd\t\t将接下来输入的文本保存到前面由 my_open 打开的文件描述符为 fd 的文件\n"); printf("*\tread\t\tfd\t\t将前面由 my_open 打开的文件描述符为 fd 的文件中读取 1024 个字节的文本\n"); printf("*\trm\t\tfilename\t删除名为 filename 的文件\n"); printf("*\texit\t\t无\t\t退出文件系统\n"); printf("*\tshow\t\t无\t\t显示全部已打开文件的fd值\n"); } void fcbcpy(int i, fcb *fileFcb) { strcpy(openfilelist[i].filename, fileFcb->filename); strcpy(openfilelist[i].exname, fileFcb->exname); openfilelist[i].attribute = fileFcb->attribute; openfilelist[i].time = fileFcb->time; openfilelist[i].data = fileFcb->data; openfilelist[i].first = fileFcb->first; openfilelist[i].length = fileFcb->length; openfilelist[i].free = fileFcb->free; openfilelist[i].ptrfcb = fileFcb; openfilelist[i].fcbstate = 0; openfilelist[i].topenfile = 1; openfilelist[i].count = 0; } void init_fat1() { fat *p = (fat*)(myvhard + BLOCKSIZE); fat *p1, *p2; p1 = p2 = p; int i; for (i = 0; i<2 * BLOCKSIZE / sizeof(fat); ++i, ++p1)(p1->id) = FREE; for (i = 0; i<7; ++i, ++p2)p2->id = END; p[5].id = 6; fat1 = (fat*)(myvhard + BLOCKSIZE); fat2 = (fat*)(myvhard + 3 * BLOCKSIZE); } void init_b0() { block0 *p_b0 = (block0*)myvhard; strcpy(p_b0->infomation, "File System made by 陈王杰 汤胜中 徐时越 包治宽"); p_b0->blocksize = BLOCKSIZE; p_b0->totalsize = SIZE / 1024; p_b0->fat_num = 2; p_b0->root = 5; p_b0->startblock = myvhard + 5 * BLOCKSIZE; p_b0->free_block = (SIZE / BLOCKSIZE) - 6; } void bak_fat1() { memcpy(myvhard + 3 * BLOCKSIZE, myvhard + BLOCKSIZE, 2 * BLOCKSIZE); } void get_time(int *data_time) { time_t now; time(&now); struct tm *nowtime; nowtime = localtime(&now); data_time[1] = nowtime->tm_hour * 2048 + nowtime->tm_min * 32 + nowtime->tm_sec / 2; /*前面的两个乘是为了移位*/ data_time[0] = (nowtime->tm_year - 80) * 512 + (nowtime->tm_mon + 1) * 32 + nowtime->tm_mday; } void check_enough_block(int block_index,int blocknum_need) { fat temp=fat1[block_index]; int i,j; for (i = 0; i < blocknum_need; ++i) { if (temp.id == END)break; if(i!=blocknum_need-1){ int need_new = blocknum_need - i - 1; for (j = 0; j < need_new; ++j)temp.id = dirst_block(); temp = fat1[temp.id]; temp.id = END; } } } void clean_openfilelist(int index) { strcpy(openfilelist[index].filename, "\0"); strcpy(openfilelist[index].exname, "\0"); openfilelist[index].attribute = 0; openfilelist[index].time = 0; openfilelist[index].data = 0; openfilelist[index].first = 0; openfilelist[index].length = 0; openfilelist[index].fcbstate = 0; openfilelist[index].ptrfcb = NULL; openfilelist[index].free = 0; openfilelist[index].topenfile = 0; openfilelist[index].count = 0; } int is_rootdir(fcb *fileFcb) { if (fileFcb->first == 5)return 1; else return 0; } int getblocknum_fromfilelen(int len) { if (len == 0)return 1; else return len % BLOCKSIZE == 0 ? (len / BLOCKSIZE) : (len / BLOCKSIZE + 1); } fcb* exist_file(fcb *fileFcb,char* filename) { int length = fileFcb->length; int flag = 0; int i; for (i = 0; i < length / sizeof(fcb); i++, ++fileFcb) { if (!strcmp(fileFcb->filename, filename)) { flag = 1; break; } if (fileFcb->free == 0) i--; } if (flag == 0)return NULL; else return fileFcb; } /*建立新文件夹时,传入为为新文件夹分配的块号便可快速完成新文件目录下的.和..的建立*/ /*root参数通常传0就好*/ void fast_dir(int dirst_block, int root) { char* block_start = (char*)myvhard + dirst_block * BLOCKSIZE; fcb* p = (fcb*)block_start; int i; for (i = 0; i<BLOCKSIZE / sizeof(fcb); ++i, ++p)p->free = 0; fcb *cur = (fcb*)block_start; fcb *father = (cur + 1); int data_time[2]; get_time(data_time); strcpy(cur->filename, "."); strcpy(father->filename, ".."); strcpy(cur->exname, "di"); strcpy(father->exname, "di"); cur->attribute = father->attribute = 0; cur->time = father->time = data_time[1]; cur->data = father->data = data_time[0]; cur->first = dirst_block; cur->length = 2 * sizeof(fcb); if (root) { father->first = cur->first; father->length = cur->length; } else { i = get_curnum(); father->first = openfilelist[i].first; father->length = openfilelist[i].length; } cur->free = father->free = 1; fat1[dirst_block].id = END; fat2[dirst_block].id = END; } void fast_dirfcb(fcb *fileFcb, char *dirname,int dirst_block) { strcpy(fileFcb->filename, dirname); strcpy(fileFcb->exname, "di"); fileFcb->attribute = 0; int time[2]; get_time(time); fileFcb->time = time[1]; fileFcb->data = time[0]; fileFcb->first = dirst_block; fileFcb->free = 1; fileFcb->length = 2 * sizeof(fcb); } /* fat的前5个给了block0,fat1,fat2*/ void my_format() { init_b0(); init_fat1(); bak_fat1(); fast_dir(5, 1); } void startsys() { myvhard = (unsigned char*)malloc(SIZE); memset(myvhard, 0, SIZE); FILE * fp; if ((fp = fopen("./my_fs", "r")) != NULL) { fread(myvhard, SIZE, 1, fp); fclose(fp); } else { printf("*\tfile not found!new file created!\n"); my_format(); } fcbcpy(0, (fcb*)(myvhard + 5 * BLOCKSIZE)); ptrcurdir = &openfilelist[0]; /*初始化后面的全部opoenfilelist项*/ int i; for (i = 1; i < MAXOPENFILE; i++) { clean_openfilelist(i); } /*设置一些全局变量*/ strcpy(currentdir, "/"); startp = ((block0 *)myvhard)->startblock; fat1 = (fat*)(myvhard + BLOCKSIZE); fat2 = (fat*)(myvhard + 3 * BLOCKSIZE); } int get_curnum() { return(ptrcurdir - openfilelist); } int dirst_block() { int i, freeBlock; fat *fat1 = (fat *)(myvhard + BLOCKSIZE); fat *fat2 = (fat *)(myvhard + BLOCKSIZE * 3); int flag = 0; for (i = 0; i < BLOCKSIZE * 2 / sizeof(fat); i++) { if (fat1->id == FREE) { flag = 1; freeBlock = i; return i; } fat1++; fat2++; } if (flag == 0) { printf("FAT满了!"); return -1; } } int get_block_num(int start_block) { int i = 1; fat *fat1 = (fat*)(myvhard + BLOCKSIZE); fat *fat_t = fat1 + start_block; if (fat_t->id == FREE)return 0; else { while (fat_t->id != END) { ++i; fat_t = fat1 + fat_t->id; } } return i; } void fast_file(fcb*fileFcb, char *filename, int dirstblock) { strcpy(fileFcb->filename, filename); strcpy(fileFcb->exname, "txt"); fileFcb->attribute = 1; int time[2]; get_time(time); fileFcb->time = time[1]; fileFcb->data = time[0]; fileFcb->first = dirstblock; fileFcb->free = 1; fileFcb->length = 0; fat *fat1 = (fat*)(myvhard + BLOCKSIZE); fat *fat2 = (fat*)(myvhard + 3*BLOCKSIZE); fat1[dirstblock].id = END; fat2[dirstblock].id = END; } void update_dir(char *filename) { if (strcmp(filename, ".") && strcmp(filename, "..")) { if (!strcmp(currentdir, "/"))strcat(currentdir, filename); else { strcat(currentdir, "/"); strcat(currentdir, filename); } } } void update_dir_father() { int last = findlast(); currentdir[last] = '\0'; } int findlast() { int i, j; i = j = 0; while (currentdir[i] != '\0') { if (currentdir[i] == '/')j = i; ++i; } if (j == 0)++j; return j; } void my_ls() { printf("filename\texname\t\ttime\t\tdata\t\tsize\n"); /*找到当前目录再openfilelist中得位置*/ int i = get_curnum(); // 读取当前目录文件的内容到内存 char *buf = (char *)malloc(1024); do_read(i, 1024, buf); fcb *fileFcb = (fcb *)buf; int num = fileFcb->length / sizeof(fcb); for (i = 0; i < num; i++, fileFcb++) { /*只有fileFCB是真的文件(目录),i才会增长*/ if (fileFcb->free == 1) { char exname[4]; int j; for (j = 0; j<3; ++j)exname[j] = fileFcb->exname[j]; exname[3] = '\0'; printf("%s\t\t%s\t\t%02d:%02d:%02d\t%02d,%02d,%02d\t%d\n", fileFcb->filename, exname, fileFcb->time / 2048, (fileFcb->time % 2048) / 32, (fileFcb->time % 32) * 2, fileFcb->data / 512 + 1980, fileFcb->data % 512 / 32, fileFcb->data % 32, fileFcb->length); } else i--; } free(buf); } void my_mkdir(char *dirname) { int i = get_curnum(); int curOpenNum = i; char *buf = (char *)malloc(1024); do_read(i, 1024, buf); fcb *fileFcb = (fcb *)buf; int fcb_num = fileFcb->length / sizeof(fcb); for (i = 0; i < fcb_num; ++i, ++fileFcb) { if (!strcmp(fileFcb->filename, dirname)) { printf("目录重名\n"); free(buf); return; } if (fileFcb->free == 0) i--; } for (i = 0; i < MAXOPENFILE; ++i) { if (openfilelist[i].topenfile == 0) { break; } } if (i == MAXOPENFILE) { printf("无剩余openuserlist项!\n"); free(buf); return; } int freeBlock = dirst_block(); if (freeBlock==-1) { printf("FAT已满!\n"); free(buf); return; } //为新目录分配fcb fileFcb = (fcb *)buf; int isroot = is_rootdir(fileFcb); for (i = 0; i < fcb_num; i++, fileFcb++) { if (!strcmp(fileFcb->filename, ".")) { fileFcb->length += sizeof(fcb); } //when root is current directory if(isroot&& !strcmp(fileFcb->filename, ".."))fileFcb->length += sizeof(fcb); if (fileFcb->free == 0)break; } //update openfilelist openfilelist[curOpenNum].length += sizeof(fcb); fast_dirfcb(fileFcb, dirname, freeBlock); fast_dir(freeBlock, 0); do_write(curOpenNum, buf, 1024, 0); free(buf); } void my_rm(char *filename) { // 读取当前目录文件的内容到内存 char *buf = (char *)malloc(1024);; int i=get_curnum(); int fd = i; do_read(i, 1024, buf); // 检查要删除的目录是否存在 fcb *fileFcb = (fcb *)buf; fileFcb = exist_file(fileFcb, filename); if (!fileFcb) { printf("%s文件(目录)不存在!\n", filename); return; } if(fileFcb->attribute==0){ printf("不能删除目录\n"); free(buf); return; } else { int j; for(j=0;j<MAXOPENFILE;++j) { if(openfilelist[j].topenfile==1 && !strcmp(openfilelist[j].filename,fileFcb->filename)) { printf("文件正在被使用"); free(buf); return; } } } // 回收磁盘块 int index = fileFcb->first; int indexT; do { indexT = fat1[index].id; fat1[index].id = FREE; fat2[index].id = FREE; index = indexT; } while (index != END); // 清空目录项 fileFcb->filename[0] = '\0'; fileFcb->free = 0; fileFcb = (fcb *)buf; // 修改目录的长度 fileFcb->length -= sizeof(fcb); do_write(fd, buf, 1024, 0); ptrcurdir->length -= sizeof(fcb); free(buf); } void my_close(int fd) { if (fd >= MAXOPENFILE) { printf("fd不是有效数字\n"); return; } else if (openfilelist[fd].topenfile == 0) { printf("文件未打开!\n"); return; } //else if (openfilelist[fd].fcbstate == 1) { // //暂时只须要改length // update_fcb(fd); //} clean_openfilelist(fd); } void my_rmdir(char *dirname) { int i = 0; char *buf = (char *)malloc(1024); i = get_curnum(); int fd = i; do_read(i, 1024, buf); // 检查要删除的目录是否存在 fcb *fileFcb = (fcb *)buf; fileFcb = exist_file(fileFcb, dirname); if (!fileFcb) { printf("%s文件(目录)不存在!\n", dirname); return; } // 检查要删除的目录文件是否为空 fcb *temp = (fcb *)(myvhard + BLOCKSIZE * fileFcb->first); if (temp->length > 2 * sizeof(fcb)) { printf("目录不为空,不可删除!\n"); return; } int flag = 0; // 检查该目录是否已经打开 for (i = 0; i < MAXOPENFILE; i++) { if (strcmp(openfilelist[i].filename, dirname) == 0) { flag = 1; break; } } if (flag == 1) {//f 把打开的目录关闭 my_close(i); } // 回收磁盘块 int index = fileFcb->first; int indexT; //length = fileFcb->length; do { indexT = fat1[index].id; fat1[index].id = FREE; fat2[index].id = FREE; index = indexT; } while (index != END); // 清空目录项,将其free设置为0便可,而后是将上层目录的长度进行更新,同时对于openlist中也要更新,由于其指向并不相同. fileFcb->filename[0] = '\0'; fileFcb->free = 0; fileFcb = (fcb *)buf; fileFcb->length -=sizeof(fcb); ptrcurdir->length -= sizeof(fcb); do_write(fd, buf, 1024, 0); free(buf); } void my_create(char *filename) { int i = get_curnum(); int curOpenNum = i; int block_num = get_block_num(openfilelist[i].first); int fcb_num = openfilelist[i].length / sizeof(fcb); char *buf = (char *)malloc(block_num * 1024); /* 把全部块的数据都读到buf里面去*/ do_read(i, block_num * 1024, buf); fcb *fileFcb = (fcb *)buf; for (i = 0; i < fcb_num; i++, ++fileFcb) { if (!strcmp(fileFcb->filename, filename)) { printf("文件重名!"); free(buf); return; break; } if (fileFcb->free == 0) i--; } int freeBlock = dirst_block(); if (freeBlock == -1) { free(buf); return; } // 在当前目录中分配FCB给新的目录fcb fileFcb = (fcb *)buf; for (i = 0; i < fcb_num; ++i, ++fileFcb) { if (!strcmp(fileFcb->filename, ".")) { fileFcb->length += sizeof(fcb); /* check if it is root directory*/ if (fileFcb->first == 5)(fileFcb + 1)->length = fileFcb->length; } if (fileFcb->free == 0) break; } fast_file(fileFcb, filename, freeBlock); ptrcurdir->length += sizeof(fcb); do_write(curOpenNum, buf, 1024, 0); free(buf); } void my_cd(char *dirname) { // 打开该目录文件 int fd = my_open(dirname); switch (fd) { case -1:break; case -2:break; case -3:update_dir_father(); break; default:update_dir(dirname); break; } } int my_open(char *filename) { int i = get_curnum(); fcb *p = (fcb*)(myvhard + (openfilelist[i].first)*BLOCKSIZE); int block_num = get_block_num(openfilelist[i].first); int fcb_num = openfilelist[i].length / sizeof(fcb); char *buf = (char *)malloc(block_num * 1024); /* 把全部块的数据都读到buf里面去*/ do_read(i, block_num * 1024, buf); fcb *fileFcb = (fcb *)buf; int flag = 0; //找到此fcb,同时检查文件存不存在 for (i = 0; i < fcb_num; i++, fileFcb++) { if (!strcmp(fileFcb->filename, filename)) { flag = 1; break; } } if (flag == 0) { printf("文件不存在!\n"); return -2; } //获得真正的pcb指针 p+=(fileFcb - (fcb*)buf); // 检查文件是否已打开 for (i = 0; i < MAXOPENFILE; i++) { if (openfilelist[i].topenfile == 1 && openfilelist[i].first == fileFcb->first) { //用first来判断是否同一个文件,注意不能用filename if (!strcmp(fileFcb->filename, "..") && (ptrcurdir->first != 5)) { //若是是打开上个目录而且不是在根目录 // 找到当前文件夹并关闭 int j = 0; for (j = 0; j<MAXOPENFILE; j++) if (openfilelist[j].free == 1 && (&openfilelist[j]) == ptrcurdir) my_close(j); // 打开上级目录 for (j = 0; j<MAXOPENFILE; j++) if (openfilelist[j].free = 1 && openfilelist[j].first == fileFcb->first) ptrcurdir = &openfilelist[j]; free(buf); printf("打开上级目录!\n"); return -3; } free(buf); printf("文件已打开!\n"); return -1; } } // 检查opefilelist是否有空余 int fd; flag = 0; for (i = 0; i < MAXOPENFILE; i++) { if (openfilelist[i].topenfile == 0) { fd = i; flag = 1; break; } } if (flag == 0) { printf("文件打开太多!\n"); free(buf); return -1; } // 填写打开分配的openfilelist fcbcpy(i, p); if(fileFcb->attribute==0)ptrcurdir = &openfilelist[i]; if(fileFcb->attribute==1)printf("打开文件的fd是%d\n", fd); free(buf); return fd; } void my_write(int fd) { if (openfilelist[fd].attribute == 0) { printf("can't write directory!\n"); return; } int writeStyle; char *text = (char *)malloc(BLOCKSIZE); int index = -1; char c_temp; unsigned short block_index=openfilelist[fd].first; if (fd >= MAXOPENFILE || fd < 0) { printf("fd超出范围\n"); return; } printf("请选择写入方式(0.覆盖写 1.追加写 2.覆盖写一行 3.追加写一行)\n"); scanf("%d", &writeStyle); getchar(); printf("请输入内容:\n"); while ((c_temp = getchar()) != '\n')text[(++index)] = c_temp; if (writeStyle == 2 || writeStyle == 3) { text[(++index)] = '\n'; writeStyle -= 2; } int len = (index + 1); int writed_len = do_write(fd, text, len, writeStyle); //返回实际写入字节数; if (writed_len != -1 && writed_len == len) { printf("写入成功,共写入 %d 个字节\n", writed_len); //update openfilelist if (writeStyle == 0) { openfilelist[fd].count=openfilelist[fd].length = len; openfilelist[fd].ptrfcb->length = len; } else { openfilelist[fd].count += len; openfilelist[fd].length = openfilelist[fd].count; openfilelist[fd].ptrfcb->length = openfilelist[fd].count; } openfilelist[fd].fcbstate = 1; } else printf("something wrong in writing!\n"); free(text); } void my_read(int fd, int len) { int i; int j = 0; for (i = 0; i < MAXOPENFILE; i++) { if (fd == 0)break; if (openfilelist[i].topenfile == 1)fd--; } fd = i; char *text = (char *)malloc(BLOCKSIZE); if (fd>MAXOPENFILE || fd<0)printf("超过操做边界\n"); else { printf("读出字节数:%d\n",do_read(fd,len,text)); text[len]='\0'; printf("%s\n", text); } free(text); } int do_read(int fd, int len, char *text) { int block_index = openfilelist[fd].first; /*读写指针*/ unsigned char *p = block_index * BLOCKSIZE + myvhard; int block_num =len%BLOCKSIZE==0?(len/BLOCKSIZE):(len / BLOCKSIZE + 1); int i, j, k = 0; //可能占据了多个盘块 for (i = 0; i < block_num; i++) { for (j = 0; j < BLOCKSIZE && k < len; j++, k++, p++)text[k] = *p; p = myvhard + BLOCKSIZE * (fat1[block_index].id); block_index = fat1[block_index].id; } return k; } int do_write(int fd, char *text, int len, int wstyle) { if (wstyle != 0&& wstyle != 1)return -1; int index = openfilelist[fd].first; unsigned char *p = index * BLOCKSIZE + myvhard; int block_num = getblocknum_fromfilelen(len); int i, j, k = 0; if (wstyle == 0) { for (i = 0; i < block_num; ++i) { for (j = 0; j < BLOCKSIZE && k < len; ++j, ++k,++p)*p = text[k]; p = myvhard + BLOCKSIZE * (fat1[index].id); index = fat1[index].id; } } else { int i; int file_len = openfilelist[fd].length; for (i = 0; i < file_len; ++i)++p; int new_file_len = file_len + len; int old_block = getblocknum_fromfilelen(file_len); int new_block = getblocknum_fromfilelen(new_file_len); check_enough_block(openfilelist[fd].first,new_block); for (i = old_block; i <= new_block; ++i) { for (j = (file_len-1)%BLOCKSIZE; j < BLOCKSIZE && k < len; ++j, ++k,++p)*p = text[k]; p = myvhard + BLOCKSIZE * (fat1[index].id); index = fat1[index].id; } } return k; } void showOpenFile() { int i; for (i = 0; i < MAXOPENFILE; i++) { if (openfilelist[i].topenfile == 1) printf("%d %s\n", i, openfilelist[i].filename); } } void my_exitsys() { //for (int i = 0; i < MAXOPENFILE; ++i) { // if (openfilelist[i].topenfile == 1 && openfilelist[i].attribute == 1 && openfilelist[i].fcbstate == 1) // update_fcb(i); //} FILE *fp; fp = fopen("./my_fs", "w"); fwrite(myvhard, SIZE, 1, fp); free(myvhard); fclose(fp); exit(0); } void switcher(char *cmd) { int fd; char command[20]; if (!strcmp(cmd, "help")) { help(); } else if (!strcmp(cmd, "info")) { info(); } else if (!strcmp(cmd, "mkdir")) { scanf("%s", command); if (strlen(command)>=8) printf("目录名过长\n"); else my_mkdir(command); } else if (!strcmp(cmd, "rmdir")) { scanf("%s", command); my_rmdir(command); } else if (!strcmp(cmd, "ls")) { my_ls(); } else if (!strcmp(cmd, "cd")) { scanf("%s", command); my_cd(command); } else if (!strcmp(cmd, "create")) { scanf("%s", command); if (strlen(command)>=8) printf("文件名过长\n"); else my_create(command); } else if (!strcmp(cmd, "write")) { scanf("%d", &fd); my_write(fd); } else if (!strcmp(cmd,"rm")) { scanf("%s",command); my_rm(command); } else if (!strcmp(cmd, "read")) { scanf("%d", &fd); my_read(fd, openfilelist[fd].length); } else if (!strcmp(cmd, "ls")) { scanf("%s", command); my_rm(command); } else if (!strcmp(cmd, "open")) { scanf("%s", command); my_open(command); } else if (!strcmp(cmd, "close")) { scanf("%d", &fd); my_close(fd); } else if (!strcmp(cmd, "exit")) { my_exitsys(); return; } else if (!strcmp(cmd, "show")) { showOpenFile(); } else { char c; while (1) { c = getchar(); if (c == '\n') break; } printf("无效指令,请从新输入:\n"); } } int main(int argc, const char * argv[]) { printf("*\t输入help以获取帮助!\n"); startsys(); char cmd[10]; while (1) { printf("%s:$", currentdir); scanf("%s", cmd); switcher(cmd); } return 0; }