⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 open.c

📁 阿基米德操作系统的源代码
💻 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 + -