diff --git a/fs/inode.c b/fs/inode.c index 85395a915dad62de9c5509d8d52e0065949543cb..dc0c88a4be90b0e36f46aaef28990e72fcbfccf7 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -269,9 +269,8 @@ static void read_inode(struct m_inode * inode) { printk("unable to read i-node block"); - *(struct d_inode *)inode = - ((struct d_inode *)bh->b_data) - [(inode->i_num-1)%INODES_PER_BLOCK]; + memcpy(inode, &(((struct d_inode *)bh->b_data) + [(inode->i_num-1)%INODES_PER_BLOCK]), sizeof(struct d_inode)); brelse(bh); unlock_inode(inode); diff --git a/kernel/main.c b/kernel/main.c index 68fd33862e41c627d4c82a28c0f32b8ca75c1af0..0fbafdb4c3f36dbae822ffd3c3ea3c4de17b030f 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -171,10 +171,8 @@ static void easy_shell() { static void run_sh() { int pid; - printf("ready to fork shell\n"); if (!(pid=fork())) { - printf("ready to start shell\n"); - execve("/et", argv,envp); + execve("/bin/et", argv,envp); } } diff --git a/tools/mkfs/mfs.cpp b/tools/mkfs/mfs.cpp index 17d55878fd65413b1a5a406f2c97e5b00be6033e..2a0e360f40c7c56864ff7d8df1cd61e33788b7b3 100644 --- a/tools/mkfs/mfs.cpp +++ b/tools/mkfs/mfs.cpp @@ -5,523 +5,33 @@ #include "minixfs.hpp" -Mode mode; - -FILE* img_file = NULL; -FILE* tfile = NULL; - -#define UPPER(size,n) ((size+((n)-1))/(n)) - -#define INODE_SIZE (sizeof(struct d_inode)) -#define INODE_BLOCKS UPPER(INODES,INODES_PER_BLOCK) -#define INODE_BUFFER_SIZE (INODE_BLOCKS * BLOCK_SIZE) - - -#define BITS_PER_BLOCK (BLOCK_SIZE<<3) - -static char super_block_buffer[BLOCK_SIZE]; -#define Super (*(struct super_block *)super_block_buffer) - -#define INODES (Super.s_ninodes) -#define ZONESIZE (Super.s_log_zone_size) -#define ZONES (Super.s_nzones) -#define MAXSIZE (Super.s_max_size) -#define IMAPS (Super.s_imap_blocks) -#define ZMAPS (Super.s_zmap_blocks) -#define MAGIC (Super.s_magic) -#define FIRSTZONE (Super.s_firstdatazone) - -#define NORM_FIRSTZONE (2+IMAPS+ZMAPS+INODE_BLOCKS) - -static char inode_map[BLOCK_SIZE * I_MAP_SLOTS]; -static char zone_map[BLOCK_SIZE * Z_MAP_SLOTS]; - -static char * inode_buffer = NULL; - -static char* images[BLOCKS] = {NULL, }; -d_inode* root = NULL; - -char* filename = NULL; -char* dir_name = NULL; - -char* src_img = NULL; -char* src_file = NULL; -char* tgt_img = NULL; -char* tgt_file = NULL; - -char* target_name = NULL; -char* extract_name = NULL; - -#define bitop(name,op) \ -static inline int name(char * addr,unsigned int nr) \ -{ \ - int __res; \ - __asm__ __volatile__("bt" op " %1,%2; adcl $0,%0" \ - :"=g" (__res) \ - :"r" (nr),"m" (*(addr)),"0" (0)); \ - return __res; \ -} - -bitop(bit,"") -bitop(setbit,"s") -bitop(clrbit,"r") - -#define mark_inode(x) (setbit(inode_map,(x))) -#define unmark_inode(x) (clrbit(inode_map,(x))) - -#define mark_zone(x) (setbit(zone_map,(x)-FIRSTZONE+1)) -#define unmark_zone(x) (clrbit(zone_map,(x)-FIRSTZONE+1)) - -void free_images() { - if (inode_buffer) { - delete[] inode_buffer; - inode_buffer = NULL; - } - - for (int i = FIRSTZONE; i < BLOCKS; i++) { - delete[] images[i]; - images[i] = NULL; - } -} - -void setup_super_block() { - memset(inode_map,0xff,sizeof(inode_map)); - memset(zone_map, 0xff,sizeof(zone_map)); - memset(super_block_buffer,0,BLOCK_SIZE); - - ZONESIZE = 0; - ZONES = BLOCKS; - INODES = BLOCKS / 3; - MAXSIZE = (7+512+512*512)*1024; - MAGIC = SUPER_MAGIC; - - IMAPS = UPPER(INODES,BITS_PER_BLOCK); - ZMAPS = UPPER(BLOCKS - NORM_FIRSTZONE,BITS_PER_BLOCK); - FIRSTZONE = NORM_FIRSTZONE; -} - -void setup_map() { - for (int i = FIRSTZONE ; ii_zone[n]) { - inode->i_zone[n] = get_new_block(); - } - return inode->i_zone[n]; - } - - n -= 7; - if (n < 512) { - if (is_create && !inode->i_zone[7]) { - inode->i_zone[7] = get_new_block(); - } - ind = get_block(inode->i_zone[7]); - if (is_create && !((unsigned short*)ind)[n]) - ((unsigned short*)ind)[n] = get_new_block(); - - return *(((unsigned short*)ind) + n); - } - - n -= 512; - if (is_create && !inode->i_zone[8]) - inode->i_zone[8] = get_new_block(); - - ind = get_block(inode->i_zone[8]); - - if (is_create && !((unsigned short*)ind)[n>>9]) - ((unsigned short*)ind)[n>>9] = get_new_block(); - - ind = get_block(*(((unsigned short*)ind) + (n >> 9))); - - if (!(*(((unsigned short*)ind) + (n & 511)))) { - *(((unsigned short*)ind) + (n & 511)) = get_new_block(); - } - - return *(((unsigned short*)ind) + (n & 511)); -} - -unsigned short bmap(struct d_inode* inode, int n) { - _bmap(inode, n, false); -} - -unsigned short create_block(struct d_inode* inode, int n) { - _bmap(inode, n, true); -} - // Read an image file. FILE* read_file() { - int i; - - img_file = fopen(filename, "r+"); - - super_block * sb = (super_block*)super_block_buffer;; - - // skip boot block - fseek(img_file, BLOCK_SIZE, 0); - - if (fread(super_block_buffer, sizeof(char), BLOCK_SIZE, img_file) != BLOCK_SIZE) { - printf("Error in super_block\n"); - return NULL; - } - int blocks = 1; - images[blocks++] = super_block_buffer; - - for (i = 0; i < sb->s_imap_blocks; i++) { - fread(inode_map + i * BLOCK_SIZE, sizeof(char), BLOCK_SIZE, img_file); - images[blocks++] = inode_map + i * BLOCK_SIZE; - } - printf("%d imap blocks read\n", i); - - for (i = 0; i < sb->s_zmap_blocks; i++) { - fread(zone_map + i * BLOCK_SIZE, sizeof(char), BLOCK_SIZE, img_file); - images[blocks++] = zone_map + i * BLOCK_SIZE; - } - printf("%d zmap blocks read\n", i); - - inode_buffer = new char[INODE_BUFFER_SIZE]; - fread(inode_buffer, sizeof(char), INODE_BUFFER_SIZE, img_file); - - printf("first zone: %d, first data zone: %u\n", - INODE_BLOCKS + 2 + sb->s_imap_blocks + sb->s_zmap_blocks, - sb->s_firstdatazone); - - for (int i = 0; i < INODE_BLOCKS; i++) { - images[2 + IMAPS + ZMAPS + i] = inode_buffer + BLOCK_SIZE * i; - } - - for (int i = FIRSTZONE; i < BLOCKS; i++) { - if (!images[i]) - images[i] = new char[BLOCK_SIZE]; - - if (BLOCK_SIZE != fread(images[i], sizeof(char), BLOCK_SIZE, img_file)) { - printf("error when read blocks, %d\n", i); - } - } - - root = iget(ROOT_INO); - - return img_file; -} - -m_inode* find_entry(m_inode* pwd, const char* name) { - char* pwd_block = get_block(bmap(pwd->p, 0)); - - for (int i = 0; i < pwd->p->i_size / sizeof(struct dir_entry); i++) { - struct dir_entry* dir = ((struct dir_entry*)pwd_block) + i; - if (strcmp(dir->name, name) == 0) { - return new m_inode(iget(dir->inode), dir->inode); - } - } return NULL; } -m_inode* namei(const char* dir_name) { - assert(dir_name[0] == '/'); - char** dirs = split(dir_name); - char** dir_list = dirs; - - m_inode* pwd = new m_inode(root, 1); - - while (*dir_list) { - m_inode* old = pwd; - pwd = find_entry(pwd, *dir_list); - delete old; - dir_list++; - } - - free_strings(dirs); - return pwd; -} - -int find_empty_inode() { - int i = 0, j = 0, k = 0; - for (i = 0; i < IMAPS; i++) { - for (j = 0; j < BLOCK_SIZE; j++) { - char bitmap = inode_map[i * BLOCK_SIZE + j]; - if ((bitmap & 0xff) < 0xff) { - for (k = 0; k < 8; k++) { - if (((1 << k) & bitmap) == 0) { - inode_map[i*BLOCK_SIZE + j] |= (1 << k); - goto found; - } - } - } - } - } - -found: - return i * BLOCK_SIZE * 8 + j * 8 + k; -} - -m_inode* get_new_dir_inode(m_inode* parent) { - int nr = find_empty_inode(); - - d_inode* inode = iget(nr); - inode->i_mode = I_DIRECTORY | 0777; - inode->i_size = 2 * sizeof(struct dir_entry); - inode->i_zone[0] = get_new_block(); - dir_entry* de = (struct dir_entry*)images[inode->i_zone[0]]; - de->inode = nr; - strncpy(de->name, ".", NAME_LEN); - - de++; - de->inode = parent ? parent->i_num : nr; - strncpy(de->name, "..", NAME_LEN); - - return new m_inode(inode, nr); -} - -m_inode* get_new_file_inode(long length) { - int nr = find_empty_inode(); - d_inode* inode = iget(nr); - inode->i_size = (unsigned int)length; - for (int i = 0; i < UPPER(inode->i_size, BLOCK_SIZE); i++) { - create_block(inode, i); - } - inode->i_mode = I_REGULAR | 0777; - - return new m_inode(inode, nr); -} - -void write_image() { - tfile = fopen(target_name, "w+"); - // skip boot block - fwrite(images[1], sizeof(char), BLOCK_SIZE, tfile); - for (int i = 1; i < BLOCKS; i++) { - fwrite(images[i], sizeof(char), BLOCK_SIZE, tfile); - } - fclose(tfile); -} - -m_inode* create_new_file(long length) { - char* parent_name = get_dir_name(tgt_file); - m_inode* parent = namei(parent_name); - const char* dname = get_entry_name(tgt_file); - printf("new file: %s\n", dname); - - m_inode* ndnode = get_new_file_inode(length); - - char* pwd_block = get_block(bmap(parent->p, 0)); - struct dir_entry* dir = (struct dir_entry*)pwd_block; - - int i = 0; - for (i = 0; i < parent->p->i_size / sizeof(struct dir_entry); i++) { - if (!dir->inode) { - dir->inode = ndnode->i_num; - strncpy(dir->name, dname, NAME_LEN); - break; - } - - if ((char*)dir > pwd_block + BLOCK_SIZE) { - pwd_block = get_block(bmap(parent->p, i / DIR_ENTRIES_PER_BLOCK)); - dir = (struct dir_entry*)pwd_block; - } - - dir++; - } - - if (i * sizeof(struct dir_entry) == parent->p->i_size) { - parent->p->i_size = (i + 1) * sizeof(struct dir_entry); - dir->inode = ndnode->i_num; - strncpy(dir->name, dname, NAME_LEN); - } - - return ndnode; -} - // Copy a file into root image. -int write_file(const char* src_file, const char* dst_file) { - read_file(); - FILE* srcf = fopen(src_file, "r"); - - m_inode* finode = create_new_file(file_length(srcf)); - dir_name = get_dir_name(tgt_file); - //list_dir(); - - int total = 0; - for (int i = 0; i < UPPER(finode->p->i_size, BLOCK_SIZE); i++) { - total += fread(get_block(bmap(finode->p, i)), sizeof(char), BLOCK_SIZE, srcf); - printf("%d block write\n", bmap(finode->p, i)); - } - printf("%d bytes read\n", total); - - write_image(); - fclose(img_file); - fclose(srcf); - return 0; -} - - -int make_dir() { - read_file(); - - char* parent_name = get_dir_name(dir_name); - m_inode* parent = namei(parent_name); - const char* dname = get_entry_name(dir_name); - printf("mkdir: %s\n", dname); - - m_inode* ndnode = get_new_dir_inode(parent); - - char* pwd_block = get_block(bmap(parent->p, 0)); - struct dir_entry* dir = (struct dir_entry*)pwd_block; - - int i = 0; - for (i = 0; i < parent->p->i_size / sizeof(struct dir_entry); i++) { - if (!dir->inode) { - dir->inode = ndnode->i_num; - strncpy(dir->name, dname, NAME_LEN); - break; - } - - if ((char*)dir > pwd_block + BLOCK_SIZE) { - pwd_block = get_block(create_block(parent->p, i / DIR_ENTRIES_PER_BLOCK)); - dir = (struct dir_entry*)pwd_block; - } - - dir++; - } - - if (i * sizeof(struct dir_entry) == parent->p->i_size) { - parent->p->i_size = (i + 1) * sizeof(struct dir_entry); - dir->inode = ndnode->i_num; - strncpy(dir->name, dname, NAME_LEN); - } - - dir_name = parent_name; - //list_dir(); - - delete[] dname; - delete parent; - delete ndnode; - - write_image(); - free_images(); - fclose(img_file); +int write_file(const char* src_file, char* dst_img, char* dst_file) { + FileSystem* fs = new FileSystem(dst_img); + fs->write_file(src_file, dst_file); + delete fs; return 0; } -void setup_image() { - int blocks = 0; - // skip boot block - images[blocks++] = super_block_buffer; - // setup super block - images[blocks++] = super_block_buffer; - for (int i = 0; i < IMAPS; i++) { - images[blocks++] = inode_map + BLOCK_SIZE * i; - } - for (int i = 0; i < ZMAPS; i++) { - images[blocks++] = zone_map + BLOCK_SIZE * i; - } - for (int i = 0; i < INODE_BLOCKS; i++) { - images[blocks++] = inode_buffer + BLOCK_SIZE * i; - } - - assert(blocks == FIRSTZONE); - while (blocks < BLOCKS) { - images[blocks++] = new char[BLOCK_SIZE]; - } -} - -void init_fs() { - FileSystem* fs = new FileSystem(filename, true); +void init_fs(char* src_img) { + FileSystem* fs = new FileSystem(src_img, true); fs->init_fs(); fs->write_image(); delete fs; } -void extract_file() { - read_file(); - m_inode* mi = namei(extract_name); - if (mi == NULL) { - printf("Can not find file %s\n", extract_name); - return; - } - - printf("file mode is %ud\n", mi->p->i_size); - printf("file nlinks is %d\n", mi->p->i_nlinks); - if (mi->p->i_size == 0) { - printf("file %s is empty.\n", extract_name); - return; - } - - FILE* extract = fopen(target_name, "w+"); - for (int i = 0; i < mi->p->i_size / BLOCK_SIZE; i++) { - int index = bmap(mi->p, i); - if (index == 0) - continue; - - if (fwrite(images[index], sizeof(char), BLOCK_SIZE, extract) != BLOCK_SIZE) { - printf("Error: write failed in extacting file"); - fclose(extract); - return; - } - } - - fclose(extract); +void extract_file(char* img_file, char* filename) { + FileSystem* fs = new FileSystem(img_file); + fs->extract_file(filename); + delete fs; } -int copy_file() { +int copy_file(char* src_img, char* tgt_img, char* src_file, char* tgt_file) { FileSystem *sfs = new FileSystem(src_img); FileSystem *tfs = new FileSystem(tgt_img); sfs->copy_to(tfs, src_file, tgt_file); @@ -531,110 +41,59 @@ int copy_file() { delete tfs; } -int main(int argc, char** argv) { - char * t; - - int i = 0; - FILE* img_file = NULL; +void usage() { +} - while (argc--) { - t = argv[i++]; +#define LENGTH 32 - if (t[0] == '-') { - if (t[1] == 'r') { - mode = READ; - } - else if (t[1] == 'l') { - argc--; - dir_name = argv[i++]; - mode = LIST; - } - else if (t[1] == 'c') { - if (t[2] == 'p') { - argc--; - src_file = argv[i++]; - mode = COPY_FILE; - } - else { - argc--; - src_file = argv[i++]; - mode = COPY; - } - } - else if (t[1] == 's') { - if (t[2] == 'f') { - argc--; - src_img = argv[i++]; - mode = COPY_FILE; - } - else { - argc--; - src_file = argv[i++]; - } - } - else if (t[1] == 't') { - if (t[2] == 'f') { - argc--; - tgt_img = argv[i++]; - } - else { - argc--; - tgt_file = argv[i++]; - } - } - else if (t[1] == 'm') { - argc--; - dir_name = argv[i++]; - mode = MAKE_DIR; - } - else if (t[1] == 'i') { - mode = INIT; - } - else if (t[1] == 'o') { - argc--; - target_name = argv[i++]; - } - else if (t[1] == 'e') { - if (t[2] == 'x') { - argc--; - extract_name = argv[i++]; - mode = EXTRACT; - } - } +int main(int argc, char** argv) { + char cmd[LENGTH]; + char src_img[LENGTH]; + char dst_img[LENGTH]; + char src_file[LENGTH]; + char dst_file[LENGTH]; + + usage(); + while (true) { + scanf("%s", cmd); + if (strcmp("exit", cmd) == 0) { + break; } - else { - filename = t; + else if (strcmp("copy", cmd) == 0 || strcmp("cp", cmd) == 0) { + printf("input source image file:"); + scanf("%s", src_img); + printf("input target image file:"); + scanf("%s", dst_img); + printf("input source file:"); + scanf("%s", src_file); + printf("input target file:"); + scanf("%s", dst_file); + + copy_file(src_img, dst_img, src_file, dst_file); + } + else if (strcmp("list", cmd) == 0 || strcmp("ls", cmd) == 0) { + printf("input source image file:"); + scanf("%s", src_img); + printf("input directory need to show:"); + scanf("%s", src_file); + FileSystem* fs = new FileSystem(src_img); + fs->list_dir(src_file); + delete fs; + } + else if (strcmp("init", cmd) == 0) { + printf("input source image file:"); + scanf("%s", src_img); + init_fs(src_img); + } + else if (strcmp("put", cmd) == 0) { + printf("input source local file:"); + scanf("%s", src_file); + printf("input target image file:"); + scanf("%s", dst_img); + printf("input target file:"); + scanf("%s", dst_file); + write_file(src_file, dst_img, dst_file); } } - - if (mode == READ) { - return 0; - } - else if (mode == LIST) { - FileSystem* fs = new FileSystem(filename); - fs->list_dir(dir_name); - delete fs; - return 0; - } - else if (mode == COPY) { - write_file(src_file, dir_name); - return 0; - } - else if (mode == MAKE_DIR) { - make_dir(); - return 0; - } - else if (mode == INIT) { - init_fs(); - } - else if (mode == EXTRACT) { - extract_file(); - } - else if (mode == COPY_FILE) { - copy_file(); - } - - - return 0; } diff --git a/tools/mkfs/minixfs.cpp b/tools/mkfs/minixfs.cpp index 2825c032ca8cd62178bcb8cd286132f9d1c38894..ae6e41546faa259aa318a1af092928bc1a53ddf9 100644 --- a/tools/mkfs/minixfs.cpp +++ b/tools/mkfs/minixfs.cpp @@ -72,7 +72,6 @@ int FileSystem::load_image(bool is_create) { _super_blk = (super_block*)_images[1]; _inode_map = _images[2]; _zone_map = _images[2 + IMAPS]; - _inode_buffer = _images[2 + IMAPS + ZMAPS]; _root = iget(ROOT_INO); @@ -101,6 +100,10 @@ m_inode* FileSystem::namei(char* dir_name) { m_inode* old = pwd; pwd = find_entry(pwd, *dir_list); delete old; + if (!pwd) { + printf("Error: file/dir %s not exists\n", *(dir_list)); + return NULL; + } dir_list++; } @@ -195,12 +198,17 @@ struct d_inode* FileSystem::iget(int nr) { int inode_block = (nr - 1) / INODES_PER_BLOCK; int index_in_block = (nr - 1) % INODES_PER_BLOCK; - return (struct d_inode*)(_inode_buffer + inode_block * BLOCK_SIZE + + return (struct d_inode*)(_images[2+IMAPS+ZMAPS+inode_block] + index_in_block * sizeof(struct d_inode)); } void FileSystem::list_dir(char* dir_name) { m_inode* inode = namei(dir_name); + if (!inode) { + printf("Error: Can not directory %s\n", dir_name); + return; + } + char* pwd_block = get_block(bmap(inode->p, 0)); for (int i = 0; i < inode->p->i_size / sizeof(struct dir_entry); i++) { @@ -217,7 +225,7 @@ void FileSystem::init_fs() { } FileSystem::~FileSystem() { - //release_images(); + release_images(); } void FileSystem::setup_map() { @@ -226,8 +234,9 @@ void FileSystem::setup_map() { memset(_inode_map,0xff, IMAPS * BLOCK_SIZE); memset(_zone_map, 0xff, ZMAPS * BLOCK_SIZE); - _inode_buffer = _images[2 + IMAPS + ZMAPS]; - memset(_inode_buffer, 0, INODE_BUFFER_SIZE); + for (int i = 0; i < INODE_BLOCKS; i++) { + memset(_images[2+IMAPS+ZMAPS+i], 0, BLOCK_SIZE); + } for (int i = FIRSTZONE ; imake_dir(parent_name); - tfs->create_new_file(tfile, smi->p->i_size); - m_inode* tmi = tfs->namei(tfile); + if (!tmi) { + tfs->make_dir(parent_name); + tmi = tfs->create_new_file(tfile, smi->p->i_size); + } if (tmi == NULL) { - tmi = tfs->get_new_dir_inode(NULL); + printf("Error: Can not create new file %s\n", tfile); + return; } - memcpy(tmi->p, smi->p, sizeof(d_inode)); - int block = 0; for (int i = 0; i < smi->p->i_size / BLOCK_SIZE; i++) { int index = bmap(smi->p, i); if (index == 0) continue; - memcpy(get_block(index), - tfs->get_block(tfs->create_block(tmi->p, block++)), BLOCK_SIZE); + memcpy(tfs->get_block(tfs->create_block(tmi->p, block++)), + get_block(index), BLOCK_SIZE); + } + + // some thing special in i_zone 0. + if (smi->p->i_size == 0) { + tmi->p->i_zone[0] = smi->p->i_zone[0]; } + + tmi->p->i_size = smi->p->i_size; + printf("isize is %d\n", tmi->p->i_size); + tmi->p->i_mode = smi->p->i_mode; + printf("imode is %d\n", tmi->p->i_mode); + tmi->p->i_nlinks = smi->p->i_nlinks; + printf("inlinks is %d\n", tmi->p->i_nlinks); + tmi->p->i_time = smi->p->i_time; + tmi->p->i_gid = smi->p->i_gid; + tmi->p->i_uid = smi->p->i_uid; } -int FileSystem::make_dir(char* dir_name) { +m_inode* FileSystem::make_dir(char* dir_name) { + m_inode* ndnode = namei(dir_name); + if (ndnode) { + return ndnode; + } + char* parent_name = get_dir_name(dir_name); m_inode* parent = namei(parent_name); + + // make sure parent's inode is not null. + if (!parent) { + parent = make_dir(parent_name); + if (!parent) { + printf("Error: can not make dir %s\n", parent_name); + return NULL; + } + } + char* dname = get_entry_name(dir_name); printf("mkdir: %s\n", dname); - m_inode* ndnode = get_new_dir_inode(parent); + ndnode = get_new_dir_inode(parent); char* pwd_block = get_block(bmap(parent->p, 0)); struct dir_entry* dir = (struct dir_entry*)pwd_block; @@ -368,9 +407,8 @@ int FileSystem::make_dir(char* dir_name) { delete[] dname; delete parent; - delete ndnode; - return 0; + return ndnode; } m_inode* FileSystem::get_new_file_inode(long length) { @@ -388,6 +426,15 @@ m_inode* FileSystem::get_new_file_inode(long length) { m_inode* FileSystem::create_new_file(char* dir_name, long length) { char* parent_name = get_dir_name(dir_name); m_inode* parent = namei(parent_name); + if (!parent) { + parent= make_dir(parent_name); + } + + if (!parent) { + printf("Error: can not create directory %s\n", parent_name); + return NULL; + } + char* dname = get_entry_name(dir_name); printf("new file: %s\n", dname); @@ -421,3 +468,58 @@ m_inode* FileSystem::create_new_file(char* dir_name, long length) { return ndnode; } +int FileSystem::write_file(const char* src_file, char* dst_file) { + FILE* srcf = fopen(src_file, "r"); + + m_inode* finode = namei(dst_file); + long length = file_length(srcf); + if (!finode) { + finode = create_new_file(dst_file, length); + } + + finode->p->i_mode = I_REGULAR | 0777; + finode->p->i_size = length; + finode->p->i_uid = 0; + finode->p->i_gid = 0; + + int total = 0; + for (int i = 0; i < UPPER(finode->p->i_size, BLOCK_SIZE); i++) { + total += fread(get_block(create_block(finode->p, i)), sizeof(char), BLOCK_SIZE, srcf); + printf("%d block write\n", bmap(finode->p, i)); + } + printf("%d bytes read\n", total); + + write_image(); + fclose(srcf); + return 0; +} + +void FileSystem::extract_file(char* file_name) { + m_inode* mi = namei(file_name); + if (mi == NULL) { + printf("Can not find file %s\n", file_name); + return; + } + + printf("file mode is %ud\n", mi->p->i_size); + printf("file nlinks is %d\n", mi->p->i_nlinks); + if (mi->p->i_size == 0) { + printf("file %s is empty and first zone is %d\n", file_name, mi->p->i_zone[0]); + return; + } + + FILE* extract = fopen(file_name, "w+"); + for (int i = 0; i < mi->p->i_size / BLOCK_SIZE; i++) { + int index = bmap(mi->p, i); + if (index == 0) + continue; + + if (fwrite(_images[index], sizeof(char), BLOCK_SIZE, extract) != BLOCK_SIZE) { + printf("Error: write failed in extacting file"); + fclose(extract); + return; + } + } + + fclose(extract); +} diff --git a/tools/mkfs/minixfs.hpp b/tools/mkfs/minixfs.hpp index 48dc088bc641cc8d1379d43446fa78671cdffe38..119e3774bfcc6450196c4de0f1f760da20f5c33c 100644 --- a/tools/mkfs/minixfs.hpp +++ b/tools/mkfs/minixfs.hpp @@ -13,8 +13,6 @@ private: char* _inode_map; char* _zone_map; - char* _inode_buffer; - d_inode* _root; int load_image(bool is_create); @@ -50,8 +48,10 @@ public: unsigned short create_block(struct d_inode* inode, int n); m_inode* get_new_dir_inode(m_inode* parent); m_inode* get_new_file_inode(long length); - int make_dir(char* dir_name); - m_inode* create_new_file(char* dir_name, long length); + m_inode* make_dir(char* dir_name); + int write_file(const char* src_file, char* dst_file); + m_inode* create_new_file(char* tgt_file, long length); + void extract_file(char* filename); }; #endif diff --git a/tools/tcc/Makefile b/tools/tcc/Makefile index ff5ba13afabebfbe339e938a2463f1f1debc5448..691c601f9d1e0c91641a22c0425f86c454cc8953 100644 --- a/tools/tcc/Makefile +++ b/tools/tcc/Makefile @@ -25,6 +25,10 @@ string.o: runtime/string.c crt0.o: runtime/crt0.S $(GCC) $(CCFLAG) -o $@ $< +et: tcc libc.a test/test.c + ./tcc test/test.c et + cp et ../mkfs/ + clean: -rm *.o -rm libc.a diff --git a/tools/tcc/include/unistd.h b/tools/tcc/include/unistd.h index 21f83d22f2d6cf991538ccb3d7d0844917805560..1147225b1d1cf4d6437008634ce1fdd8cbcc98a8 100644 --- a/tools/tcc/include/unistd.h +++ b/tools/tcc/include/unistd.h @@ -152,5 +152,7 @@ extern int errno; int write(int fildes, const char * buf, off_t count); int read(int fildes, const char * buf, off_t count); int rmdir(const char* pathname); +int execve(const char * filename, char ** argv, char ** envp); +int fork(); #endif diff --git a/tools/tcc/runtime/sys_call.c b/tools/tcc/runtime/sys_call.c index 6d252efb5081fc8e81151fbdc7fb948cd531b03e..cc90605e6458d665a0cc36417e01c2b8d01bddd4 100644 --- a/tools/tcc/runtime/sys_call.c +++ b/tools/tcc/runtime/sys_call.c @@ -7,3 +7,12 @@ _syscall3(int,read,int,fd,const char *,buf,off_t,count) _syscall2(int, mkdir, const char *, pathname, mode_t, mode) _syscall1(int, rmdir, const char *, pathname) _syscall1(int, chdir, const char *, filename) +_syscall3(int,execve,const char *,file,char **,argv,char **,envp) +_syscall0(int,fork); + +_syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options) + +pid_t wait(int * wait_stat) { + return waitpid(-1,wait_stat,0); +} + diff --git a/tools/tcc/test/test.c b/tools/tcc/test/test.c index 10098a0c397371448345c426e4ecbc2bf54969d4..074654582c7c613d1a4e212bcefe576d0ee9dc2b 100644 --- a/tools/tcc/test/test.c +++ b/tools/tcc/test/test.c @@ -5,8 +5,12 @@ #define MAX_LEN 128 char buf[MAX_LEN]; +char* argv[] = {"/usr/bin", NULL}; +char* envp[] = {"HOME=/usr/root", NULL}; + int main(int argc, char** argv, char** envp) { int i; + pid_t pid; while (1) { printf(">>>"); @@ -15,8 +19,19 @@ int main(int argc, char** argv, char** envp) { if (strcmp(buf, "exit") == 0) { break; } - else { - printf("%s\n", buf); + else if (strcmp(buf, "sh") == 0) { + printf("got sh\n"); + if (!(pid = fork())) { + execve("/bin/sh", argv, envp); + } + wait(pid); + } + else if (strcmp(buf, "ls") == 0) { + printf("got ls\n"); + if (!(pid = fork())) { + execve("/usr/bin/ls", argv, envp); + } + wait(pid); } }