static void do_log_procs(FileBuff log) { DIR* dir = opendir("/proc"); struct dirent* entry; do_log_uptime(log); while ((entry = readdir(dir)) != NULL) { /* only match numeric values */ char* end; int pid = strtol( entry->d_name, &end, 10); if (end != NULL && end > entry->d_name && *end == 0) { char filename[32]; char buff[1024]; char cmdline[1024]; int len; int fd; /* read command line and extract program name */ snprintf(filename,sizeof(filename),"/proc/%d/cmdline",pid); proc_read(filename, cmdline, sizeof(cmdline)); /* read process stat line */ snprintf(filename,sizeof(filename),"/proc/%d/stat",pid); fd = open(filename,O_RDONLY); if (fd >= 0) { len = unix_read(fd, buff, sizeof(buff)-1); close(fd); if (len > 0) { int len2 = strlen(cmdline); if (len2 > 0) { /* we want to substitute the process name with its real name */ const char* p1; const char* p2; buff[len] = 0; p1 = strchr(buff, '('); p2 = strchr(p1, ')'); file_buff_write(log, buff, p1+1-buff); file_buff_write(log, cmdline, strlen(cmdline)); file_buff_write(log, p2, strlen(p2)); } else { /* no substitution */ file_buff_write(log,buff,len); } } } } } closedir(dir); do_log_ln(log); }
static void do_log_file(FileBuff log, const char* procfile) { char buff[1024]; int fd; do_log_uptime(log); /* append file content */ fd = open(procfile,O_RDONLY); if (fd >= 0) { close_on_exec(fd); for (;;) { int ret; ret = unix_read(fd, buff, sizeof(buff)); if (ret <= 0) break; file_buff_write(log, buff, ret); if (ret < (int)sizeof(buff)) break; } close(fd); } do_log_ln(log); }
static void do_log_uptime(FileBuff log) { char buff[65]; int len; snprintf(buff,sizeof(buff),"%lld\n",get_uptime_jiffies()); len = strlen(buff); file_buff_write(log, buff, len); }
static void do_log_uptime(FileBuff log) { char buff[65]; struct timeval now; gettimeofday(&now, 0); long long jiffies = (now.tv_sec * 100LL + now.tv_usec / 10000) - (start_time.tv_sec * 100LL + start_time.tv_usec / 10000); int len; snprintf(buff,sizeof(buff),"%lld\n",jiffies); len = strlen(buff); file_buff_write(log, buff, len); }
static void do_log_uptime(FileBuff log) { char buff[65]; int fd, ret, len; fd = open("/proc/uptime",O_RDONLY); if (fd >= 0) { int ret; ret = unix_read(fd, buff, 64); close(fd); buff[64] = 0; if (ret >= 0) { long long jiffies = 100LL*strtod(buff,NULL); int len; snprintf(buff,sizeof(buff),"%lld\n",jiffies); len = strlen(buff); file_buff_write(log, buff, len); } } }
/* 函数功能:写文件 输入参数:进程指针 p_tcb 文件fd fd 写缓冲 buf 写大小 count 字节 输出参数:成功返回实际写入字节数,失败返回-1 */ int fs_write(int fd,void * buf,int offset,int count,TCB* p_tcb) { File_Desc* p_fd; Inode* p_inode; buf = va2pa(p_tcb->pdb,buf); p_fd = p_tcb->filp[fd]; p_inode = p_fd->fd_inode; //---------------------------------------------------------- // 字符设备文件 if(p_inode->i_mode == I_MODE_CHAR) { MSG msg; msg.type = TTY_MSG_UNION; msg.msg_union.tty_msg.para = DEV_WRITE; msg.msg_union.tty_msg.sub_device = MINOR(p_inode->i_start_sect); msg.msg_union.tty_msg.req_buf = buf; msg.msg_union.tty_msg.req_count = count; disable_int(); if(tty_has_msg_tmp == 0) { if(sendrecv(BOTH,dd_map[MAJAR(p_inode->i_start_sect)],&msg) == -1) msg.msg_union.tty_msg.req_count = -1; enable_int(); return msg.msg_union.tty_msg.req_count; } enable_int(); return -1; } //---------------------------------------------------------- // 以下是普通文件 int cnt = file_buff_write( buf, p_fd->fd_inode, offset + p_fd->fd_pos, count); assert(cnt != -1); p_fd->fd_pos += offset + cnt; return cnt; }
static void do_log_ln(FileBuff log) { file_buff_write(log, "\n", 1); }
/* 函数功能:删除普通文件 输入参数:文件名 pathname 删除方式 flags 输出参数:成功返回0,失败返回-1 */ int fs_delete(char * pathname,int flags) { DEV_Inode* p_devinode; int inode_nr; Inode* p_inode; Dir_Entry* p_de; int i,j,k; // 读目录文件,获取Dir_Entry 和 inode_nr int file_offset = 0; int de_nr = 0; for(i = 0,inode_nr = 0;i < ROOT_SECTS;i++,file_offset += SECTOR_SIZE) { file_buff_read(fsbuf,p_inode_de,file_offset,SECTOR_SIZE); for(j = 0,p_de = (Dir_Entry*)fsbuf;j < DIR_ENT_PER_SECT;j++,p_de++) { if(strcmp(p_de->name,pathname) == 0) { inode_nr = p_de->inode_nr; de_nr += j; break; } } if(inode_nr != 0) break; de_nr += DIR_ENT_PER_SECT; } // 目录中寻找结束 if(inode_nr == 0) { printk("can not find the file for delete ! %s\n",pathname); return -1; // 待删除的文件不存在 } if(inode_nr < 5) { printk("can not delete this file! %s\n",pathname); return -1; // 前4个文件不能删除。1:"." 2-4:tty0-tty2 } // 检测inode_table中是否有inode_nr,如果没有,则表示没有进程在使用该文件,可以删除 for(p_inode = inode_table;p_inode < inode_table + MAX_ALL_INODE;p_inode++) { if(p_inode->i_num == inode_nr && p_inode->i_cnt != 0) { printk("can not delete the file ! %s\n",pathname); return -1; // 当前有进程在使用该文件,所以不能删除 } } // 设备中释放imap,smap,Dir_Entry // imap int sect = IMAP_1ST_SECTS + inode_nr / 8 / SECTOR_SIZE; hd_read(ROOT_DEV,fsbuf,SECTOR_SIZE * sect,1); fsbuf[inode_nr / 8 % SECTOR_SIZE] &= (U8)~(1 << (inode_nr % 8) ); hd_write(ROOT_DEV,fsbuf,SECTOR_SIZE * sect,1); // smap sect = INODE_1ST_SECTS + inode_nr / INODE_PER_SECT; // 获取devinode hd_read(ROOT_DEV,fsbuf,SECTOR_SIZE * sect,1); p_devinode = (DEV_Inode*)fsbuf; p_devinode += inode_nr % INODE_PER_SECT; int start_sect = p_devinode->i_start_sect; int nr_sects = p_devinode->i_nr_sects; i = start_sect / 8 / SECTOR_SIZE; // 所在扇区号 j = start_sect / 8 % SECTOR_SIZE; // 扇区内字节号 k = start_sect % 8; // 字内位号 //printk("start_sect:%d,i:%d,j:%d,k:%d\n",start_sect + DAT_1ST_SECT,i,j,k); while(nr_sects > 0) // 释放smap { hd_read(ROOT_DEV,fsbuf,SECTOR_SIZE * (i + SMAP_1ST_SECTS),1); while(j < SECTOR_SIZE && nr_sects >0) { if(8 - k >= nr_sects) // 该字节内解决问题 { while(nr_sects-- > 0) { fsbuf[j] &= (char)~(1 << k++); } break; } else // 该字节内解决不了问题 { if(k == 0) // 全0 { fsbuf[j] = 0; nr_sects -= 8; } else // 非全0 { while(k < 8) { fsbuf[j] &= (char)~(1 << k++); nr_sects--; } } j++; k = 0; } } //printk("i:%d,j:%d,k:%d\n",i,j,k); hd_write(ROOT_DEV,fsbuf,SECTOR_SIZE * (i + SMAP_1ST_SECTS),1); i++; j = 0; } // Dir_Entry Dir_Entry de; de.inode_nr = 0; //printk("de_nr:%d ",de_nr); file_buff_write(&de,p_inode_de,de_nr * sizeof(Dir_Entry),sizeof(Dir_Entry)); sync_buff(p_inode_de,0); // 0:不释放缓冲 1:同步之后释放缓冲 // 成功返回0 return 0; }
/* 函数功能:创建普通文件 输入参数:文件名 pathname 输出参数:0 创建失败,非0 新文件在设备中的inode_nr */ int create_file(char * pathname) { int inode_nr = 0; int start_sect = 0; int i,j,k; // 在imap中找一个空位 for(i = 0;i < NR_IMAP_SECTS ;i++) { hd_read(ROOT_DEV,fsbuf,SECTOR_SIZE * (IMAP_1ST_SECTS + i),1); for(j = 0;j < SECTOR_SIZE;j++) { if(fsbuf[j] == (char)0xff) continue; for(k = 0;k < 8;k++) { if(( fsbuf[j] & (1<<k) ) == 0) { // 此时第i扇区,第j字节,第k位为待找的空位 //printk("imap find3\n"); inode_nr = SECTOR_SIZE * i * 8 + j * 8 + k; if(inode_nr == 0) continue; //printk("imap find4,inode_nr: %d\n",inode_nr); fsbuf[j] |= (1 << k); hd_write(ROOT_DEV,fsbuf,SECTOR_SIZE * (IMAP_1ST_SECTS + i),1); break; } } if(inode_nr != 0) break; } if(inode_nr != 0) break; } if(inode_nr == 0) { printk("imap full----"); return 0; // 没有空位 } // 在smap中找 inode_nr对应的 SECTS_PER_FILE 个连续空位,然后全部置1 for(i = 0;i < NR_SMAP_SECTS;i++) // { hd_read(ROOT_DEV,fsbuf,SECTOR_SIZE * (SMAP_1ST_SECTS + i),1); for(j = 0;j < SECTOR_SIZE;j++) { if(fsbuf[j] == (char)0xff) continue; for(k = 0;k < 8;k++) { if((fsbuf[j] & (1 << k)) == 0) { // 此时第i扇区,第j字节,第k位为待找的空位 //printk("i:%d j:%d k:%d\n",i,j,k); start_sect = SECTOR_SIZE * i * 8 + j * 8 + k; int nr_sects = SECTS_PER_FILE; while(nr_sects > 0) // 填充smap { hd_read(ROOT_DEV,fsbuf,SECTOR_SIZE * (i + SMAP_1ST_SECTS),1); while(j < SECTOR_SIZE && nr_sects >0) { if(8 - k >= nr_sects) // 该字节内解决问题 { while(nr_sects-- > 0) { if(fsbuf[j] & (char)(1 << k)) { printk("i:%d j:%d k:%d\n",i,j,k); printk("OMG retry1!\n"); goto repeat; } fsbuf[j] |= (char)(1 << k++); } hd_write(ROOT_DEV,fsbuf,SECTOR_SIZE * (i + SMAP_1ST_SECTS),1); goto smapOK; } else // 该字节内解决不了问题 { if(k == 0) // 全1 { if(fsbuf[j] != 0) { printk("i:%d j:%d k:%d\n",i,j,k); printk("OMG retry2!\n"); goto repeat; } fsbuf[j] = 0xff; nr_sects -= 8; } else // 非全1 { while(k < 8) { if(fsbuf[j] & (char)(1 << k)) { printk("i:%d j:%d k:%d\n",i,j,k); printk("OMG retry3!\n"); goto repeat; } fsbuf[j] |= (char)(1 << k++); nr_sects--; } } j++; k = 0; } } hd_write(ROOT_DEV,fsbuf,SECTOR_SIZE * (i + SMAP_1ST_SECTS),1); i++; j = 0; } } repeat: ; } } } smapOK: if(start_sect == 0) { printk("smap full2----"); return 0; // 没有空位 } // devinode赋值 int offset = (SECTOR_SIZE * INODE_1ST_SECTS + inode_nr * INODE_SIZE) & ~0x1ff; hd_read(ROOT_DEV,fsbuf,offset,1); DEV_Inode* p_devinode = (DEV_Inode*)fsbuf; p_devinode += inode_nr % INODE_PER_SECT; p_devinode->i_mode = I_MODE_FILE; p_devinode->i_size = FILE_MAX_SIZE; p_devinode->i_start_sect = start_sect; p_devinode->i_nr_sects = SECTS_PER_FILE; printk("new file %s start_sect :%d sects: %d\n",pathname,start_sect,SECTS_PER_FILE); hd_write(ROOT_DEV,fsbuf,offset,1); // Dir_Entry // 在root中找一个空位 Dir_Entry* p_de; int file_offset = 0; int de_nr = 0; for(i = 0;i < ROOT_SECTS;i++,file_offset += SECTOR_SIZE) { file_buff_read(fsbuf,p_inode_de,file_offset,SECTOR_SIZE); for(j = 0,p_de = (Dir_Entry*)fsbuf;j < DIR_ENT_PER_SECT;j++,p_de++) { if(p_de->inode_nr == 0 && (i !=0 || j != 0)) // 第0号位置保留 { de_nr += j; //printk("de_nr:%d ",de_nr); Dir_Entry de; de.inode_nr = inode_nr; memcopy(de.name,pathname,MAX_FILENAME_LEN); file_buff_write(&de,p_inode_de,de_nr * sizeof(Dir_Entry),sizeof(Dir_Entry)); sync_buff(p_inode_de,0); // 0:不释放缓冲 1:同步之后释放缓冲 // 返回inode_nr printk("create file success: %s\n",pathname); return inode_nr; // 返回inode_nr 0:失败,非0:成功 } } de_nr += DIR_ENT_PER_SECT; } printk("Dir_Entry empty\n"); return 0; // 没有找到Dir_Entry }