📄 open.c
字号:
/////////////////////////////////////////////////
#include "general.h"
#include "s_isdirreg.h"
#include "hd_info_struct.h"
#include "dir_entry.h"
#include "msdos_dir_entry.h"
#include "d_inode.h"
#include "m_inode.h"
#include "buffer_head.h"
#include "fat_cache.h"
#include "file.h"
#include "hd_request_struct.h"
#include "super_block.h"
#include "common_head.h"
/////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
int open_namei(const char * pathname, unsigned char flag, unsigned char mode,struct m_inode ** res_inode,unsigned char * buf,unsigned long length)
{
struct m_inode * dir, * inode;
struct buffer_head * bh;
struct dir_entry * de;
const char * basename, * basename0;
int idev,inr,namelen;
char temp_char;
*res_inode = NULL;
if (!(dir = dir_namei(pathname,&namelen,&basename)))
return 0;
if (!namelen) { /* special case: '/usr/' etc */
iput(dir);
return 0;
}
/////////////////////////////////////////////
if (buf != NULL)
{
basename0 = basename;
while ((temp_char = get_gs_byte(basename0++)) != 0)
put_gs_byte(temp_char,buf++);
put_gs_byte(0,buf++);
}
/////////////////////////////////////////////
bh = find_entry(dir,basename,namelen,&de);
if (!bh) {
if (!(flag & O_CREAT) || (mode & 0xf8)) {
iput(dir);
return 0;
}
inode = new_inode(dir->i_dev);
if (!inode) {
iput(dir);
return 0;
}
bh = add_entry(dir,basename,namelen,&de);
if (!bh) {
inode->i_nlinks--;
iput(inode);
iput(dir);
return 0;
}
de->inode = inode->i_num;
bh->b_dirt = 1;
brelse(bh);
dir->i_mtime = file_datetime;
dir->i_dirt = 1;
iput(dir);
inode->i_mode = mode | I_REGULAR;
inode->i_mtime = file_datetime;
inode->i_dirt = 1;
*res_inode = inode;
return 1;
}
idev = dir->i_dev;
inr = de->inode;
brelse(bh);
iput(dir);
if (flag & O_EXCL)
return 0;
if (!(inode = iget(idev,inr)))
return 0;
if (!S_ISREG(inode->i_mode)){
iput(inode);
return 0;
}
if ((inode->i_mode & flag & 0x07) != (flag & 0x07)){
iput(inode);
return 0;
}
if (flag & O_TRUNC) {
if (inode->i_count > 1) {
iput(inode);
return 0;
}
truncate(inode);
}
*res_inode = inode;
return 1;
}
/////////////////////////////////////////////////////////////int the_open(const char * filename,unsigned long flag,unsigned long mode,unsigned char * buf,unsigned long length){ struct m_inode * inode;
struct file * filep; int fd , retval; unsigned char temp_flag;
unsigned char temp_mode;
temp_flag = flag;
temp_mode = mode;
if (temp_flag & (~(O_APPEND | O_TRUNC | O_EXCL | O_CREAT | O_RDWR)))
return -1;
if (temp_flag & (O_APPEND | O_TRUNC))
temp_flag = temp_flag | O_WRONLY;
for (fd = 0, filep = file_table; fd < NR_FILE; fd++ , filep++)
if (!filep->f_count)
break;
if (fd >= NR_FILE)
return -1;
if (!(retval = open_namei(filename,temp_flag,temp_mode,&inode,buf,length))) return -1; filep->f_inode = inode;
filep->f_pos = 0; filep->f_flag = temp_flag & (O_APPEND | O_RDWR);
filep->f_count = 1;
return fd;}////////////////////////////////////////////////////////////////////////////////////////////////////
int sys_dirstart(const char * pathname,const char * basename,unsigned char * buf,unsigned long length)
{
const char * temp_basename;
unsigned long namelen = 0;
struct m_inode * dir, * inode;
struct buffer_head * bh;
struct dir_entry * de;
char * p;
int idev, inr, i;
int ret_val = 0;
if ((dir_file.f_count) || !(dir = namei(pathname)))
return -1;
if (!S_ISDIR(dir->i_mode))
{
iput(dir);
return -1;
}
if (basename)
{
temp_basename = basename;
while (get_gs_byte(temp_basename++))
namelen++;
if (!namelen || (namelen > NAME_LEN) || !buf || (length < NAME_LEN + 10))
{
iput(dir);
return -1;
}
bh = find_entry(dir,basename,namelen,&de);
if (bh)
{
idev = dir->i_dev;
inr = de->inode;
inode = iget(idev,inr);
if (!inode)
{
brelse(bh);
iput(dir);
return -1;
}
if (S_ISDIR(inode->i_mode))
{
iput(dir);
dir = inode;
}
else
{
put_gs_byte(1,buf++);
p = (char *)de;
p = p + 4;
for (i = 0; i < NAME_LEN; i++)
put_gs_byte(*p++,buf++);
put_gs_byte(inode->i_mode,buf++);
put_gs_long(inode->i_mtime,(long *)buf);
buf = buf + 4;
put_gs_long(inode->i_size,(long *)buf);
buf = buf + 4;
iput(inode);
ret_val = 1;
}
brelse(bh);
}
else
{
put_gs_byte(0,buf++);
ret_val = 1;
}
}
dir_file.f_inode = dir;
dir_file.f_pos = 0;
dir_file.f_flag = 0;
dir_file.f_count = 1;
return ret_val;
}
int sys_dirend(void)
{
if (dir_file.f_count == 0)
return -1;
iput(dir_file.f_inode);
dir_file.f_count = 0;
return 0;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
int sys_open(const char * filename,unsigned long flag,unsigned long mode)
{
return the_open(filename, flag, mode, NULL, 0);
}
int sys_openEX(const char * filename,unsigned long flag,unsigned long mode,unsigned char * buf,unsigned long length)
{
return the_open(filename, flag, mode, buf, length);
}
int sys_create(const char * pathname, unsigned long mode){ return the_open(pathname, O_CREAT | O_EXCL, mode, NULL, 0);}int sys_close(int fd){ if ((fd >= NR_FILE) || (file_table[fd].f_count == 0))
return -1; if (--file_table[fd].f_count) return 0; iput(file_table[fd].f_inode); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -