parent
							
								
									c5843e39b8
								
							
						
					
					
						commit
						02bc2f1c73
					
				@ -0,0 +1,270 @@
 | 
				
			||||
/*
 | 
				
			||||
 *  linux/fs/open.c
 | 
				
			||||
 *
 | 
				
			||||
 *  (C) 1991  Linus Torvalds
 | 
				
			||||
 */
 | 
				
			||||
 | 
				
			||||
#include <string.h>
 | 
				
			||||
#include <errno.h>
 | 
				
			||||
#include <fcntl.h>
 | 
				
			||||
#include <sys/types.h>
 | 
				
			||||
#include <utime.h>
 | 
				
			||||
#include <sys/stat.h>
 | 
				
			||||
#include <const.h>
 | 
				
			||||
#include <linux/sched.h>
 | 
				
			||||
#include <linux/tty.h>
 | 
				
			||||
#include <linux/kernel.h>
 | 
				
			||||
#include <asm/segment.h>
 | 
				
			||||
 | 
				
			||||
int sys_ustat(int dev, struct ustat * ubuf)
 | 
				
			||||
{
 | 
				
			||||
	return -ENOSYS;
 | 
				
			||||
}
 | 
				
			||||
 | 
				
			||||
int sys_utime(char * filename, struct utimbuf * times)
 | 
				
			||||
{
 | 
				
			||||
	struct m_inode * inode;
 | 
				
			||||
	long actime,modtime;
 | 
				
			||||
 | 
				
			||||
	if (!(inode=namei(filename)))
 | 
				
			||||
		return -ENOENT;
 | 
				
			||||
	if (times) {
 | 
				
			||||
		actime = get_fs_long((unsigned long *) ×->actime);
 | 
				
			||||
		modtime = get_fs_long((unsigned long *) ×->modtime);
 | 
				
			||||
	} else
 | 
				
			||||
		actime = modtime = CURRENT_TIME;
 | 
				
			||||
	inode->i_atime = actime;
 | 
				
			||||
	inode->i_mtime = modtime;
 | 
				
			||||
	inode->i_dirt = 1;
 | 
				
			||||
	iput(inode);
 | 
				
			||||
	return 0;
 | 
				
			||||
}
 | 
				
			||||
 | 
				
			||||
/*
 | 
				
			||||
 * XXX should we use the real or effective uid?  BSD uses the real uid,
 | 
				
			||||
 * so as to make this call useful to setuid programs.
 | 
				
			||||
 */
 | 
				
			||||
int sys_access(const char * filename,int mode)
 | 
				
			||||
{
 | 
				
			||||
	struct m_inode * inode;
 | 
				
			||||
	int res, i_mode;
 | 
				
			||||
 | 
				
			||||
	mode &= 0007;
 | 
				
			||||
	if (!(inode=namei(filename)))
 | 
				
			||||
		return -EACCES;
 | 
				
			||||
	i_mode = res = inode->i_mode & 0777;
 | 
				
			||||
	iput(inode);
 | 
				
			||||
	if (current->uid == inode->i_uid)
 | 
				
			||||
		res >>= 6;
 | 
				
			||||
	else if (current->gid == inode->i_gid)
 | 
				
			||||
		res >>= 6;
 | 
				
			||||
	if ((res & 0007 & mode) == mode)
 | 
				
			||||
		return 0;
 | 
				
			||||
	/*
 | 
				
			||||
	 * XXX we are doing this test last because we really should be
 | 
				
			||||
	 * swapping the effective with the real user id (temporarily),
 | 
				
			||||
	 * and then calling suser() routine.  If we do call the
 | 
				
			||||
	 * suser() routine, it needs to be called last. 
 | 
				
			||||
	 */
 | 
				
			||||
	if ((!current->uid) &&
 | 
				
			||||
	    (!(mode & 1) || (i_mode & 0111)))
 | 
				
			||||
		return 0;
 | 
				
			||||
	return -EACCES;
 | 
				
			||||
}
 | 
				
			||||
 | 
				
			||||
int sys_chdir(const char * filename)
 | 
				
			||||
{
 | 
				
			||||
	struct m_inode * inode;
 | 
				
			||||
 | 
				
			||||
	if (!(inode = namei(filename)))
 | 
				
			||||
		return -ENOENT;
 | 
				
			||||
	if (!S_ISDIR(inode->i_mode)) {
 | 
				
			||||
		iput(inode);
 | 
				
			||||
		return -ENOTDIR;
 | 
				
			||||
	}
 | 
				
			||||
	iput(current->pwd);
 | 
				
			||||
	current->pwd = inode;
 | 
				
			||||
	return (0);
 | 
				
			||||
}
 | 
				
			||||
 | 
				
			||||
int sys_chroot(const char * filename)
 | 
				
			||||
{
 | 
				
			||||
	struct m_inode * inode;
 | 
				
			||||
 | 
				
			||||
	if (!(inode=namei(filename)))
 | 
				
			||||
		return -ENOENT;
 | 
				
			||||
	if (!S_ISDIR(inode->i_mode)) {
 | 
				
			||||
		iput(inode);
 | 
				
			||||
		return -ENOTDIR;
 | 
				
			||||
	}
 | 
				
			||||
	iput(current->root);
 | 
				
			||||
	current->root = inode;
 | 
				
			||||
	return (0);
 | 
				
			||||
}
 | 
				
			||||
 | 
				
			||||
int sys_chmod(const char * filename,int mode)
 | 
				
			||||
{
 | 
				
			||||
	struct m_inode * inode;
 | 
				
			||||
 | 
				
			||||
	if (!(inode=namei(filename)))
 | 
				
			||||
		return -ENOENT;
 | 
				
			||||
	if ((current->euid != inode->i_uid) && !suser()) {
 | 
				
			||||
		iput(inode);
 | 
				
			||||
		return -EACCES;
 | 
				
			||||
	}
 | 
				
			||||
	inode->i_mode = (mode & 07777) | (inode->i_mode & ~07777);
 | 
				
			||||
	inode->i_dirt = 1;
 | 
				
			||||
	iput(inode);
 | 
				
			||||
	return 0;
 | 
				
			||||
}
 | 
				
			||||
 | 
				
			||||
int sys_chown(const char * filename,int uid,int gid)
 | 
				
			||||
{
 | 
				
			||||
	struct m_inode * inode;
 | 
				
			||||
 | 
				
			||||
	if (!(inode=namei(filename)))
 | 
				
			||||
		return -ENOENT;
 | 
				
			||||
	if (!suser()) {
 | 
				
			||||
		iput(inode);
 | 
				
			||||
		return -EACCES;
 | 
				
			||||
	}
 | 
				
			||||
	inode->i_uid=uid;
 | 
				
			||||
	inode->i_gid=gid;
 | 
				
			||||
	inode->i_dirt=1;
 | 
				
			||||
	iput(inode);
 | 
				
			||||
	return 0;
 | 
				
			||||
}
 | 
				
			||||
 | 
				
			||||
int sys_open(const char * filename,int flag,int mode)
 | 
				
			||||
{
 | 
				
			||||
	struct m_inode * inode;
 | 
				
			||||
	struct file * f;
 | 
				
			||||
	int i,fd;
 | 
				
			||||
 | 
				
			||||
	mode &= 0777 & ~current->umask;
 | 
				
			||||
	for(fd=0 ; fd<NR_OPEN ; fd++)
 | 
				
			||||
		if (!current->filp[fd])
 | 
				
			||||
			break;
 | 
				
			||||
	if (fd>=NR_OPEN)
 | 
				
			||||
		return -EINVAL;
 | 
				
			||||
	current->close_on_exec &= ~(1<<fd);
 | 
				
			||||
	f=0+file_table;
 | 
				
			||||
	for (i=0 ; i<NR_FILE ; i++,f++)
 | 
				
			||||
		if (!f->f_count) break;
 | 
				
			||||
	if (i>=NR_FILE)
 | 
				
			||||
		return -EINVAL;
 | 
				
			||||
	(current->filp[fd]=f)->f_count++;
 | 
				
			||||
	if ((i=open_namei(filename,flag,mode,&inode))<0) {
 | 
				
			||||
		current->filp[fd]=NULL;
 | 
				
			||||
		f->f_count=0;
 | 
				
			||||
		return i;
 | 
				
			||||
	}
 | 
				
			||||
/* ttys are somewhat special (ttyxx major==4, tty major==5) */
 | 
				
			||||
	if (S_ISCHR(inode->i_mode))
 | 
				
			||||
		if (MAJOR(inode->i_zone[0])==4) {
 | 
				
			||||
			if (current->leader && current->tty<0) {
 | 
				
			||||
				current->tty = MINOR(inode->i_zone[0]);
 | 
				
			||||
				tty_table[current->tty].pgrp = current->pgrp;
 | 
				
			||||
			}
 | 
				
			||||
		} else if (MAJOR(inode->i_zone[0])==5)
 | 
				
			||||
			if (current->tty<0) {
 | 
				
			||||
				iput(inode);
 | 
				
			||||
				current->filp[fd]=NULL;
 | 
				
			||||
				f->f_count=0;
 | 
				
			||||
				return -EPERM;
 | 
				
			||||
			}
 | 
				
			||||
/* Likewise with block-devices: check for floppy_change */
 | 
				
			||||
	if (S_ISBLK(inode->i_mode))
 | 
				
			||||
		check_disk_change(inode->i_zone[0]);
 | 
				
			||||
	f->f_mode = inode->i_mode;
 | 
				
			||||
	f->f_flags = flag;
 | 
				
			||||
	f->f_count = 1;
 | 
				
			||||
	f->f_inode = inode;
 | 
				
			||||
	f->f_pos = 0;
 | 
				
			||||
	return (fd);
 | 
				
			||||
}
 | 
				
			||||
 | 
				
			||||
int sys_creat(const char * pathname, int mode)
 | 
				
			||||
{
 | 
				
			||||
	return sys_open(pathname, O_CREAT | O_TRUNC, mode);
 | 
				
			||||
}
 | 
				
			||||
 | 
				
			||||
int sys_close(unsigned int fd)
 | 
				
			||||
{	
 | 
				
			||||
	struct file * filp;
 | 
				
			||||
 | 
				
			||||
	if (fd >= NR_OPEN)
 | 
				
			||||
		return -EINVAL;
 | 
				
			||||
	current->close_on_exec &= ~(1<<fd);
 | 
				
			||||
	if (!(filp = current->filp[fd]))
 | 
				
			||||
		return -EINVAL;
 | 
				
			||||
	current->filp[fd] = NULL;
 | 
				
			||||
	if (filp->f_count == 0)
 | 
				
			||||
		panic("Close: file count is 0");
 | 
				
			||||
	if (--filp->f_count)
 | 
				
			||||
		return (0);
 | 
				
			||||
	iput(filp->f_inode);
 | 
				
			||||
	return (0);
 | 
				
			||||
}
 | 
				
			||||
long sys_getcwd(char *buf,size_t size){
 | 
				
			||||
	int entries;
 | 
				
			||||
	int block,i;
 | 
				
			||||
	int num = 19;
 | 
				
			||||
	char s[20][NAME_LEN];
 | 
				
			||||
	struct buffer_head * bh;
 | 
				
			||||
	struct dir_entry * de;
 | 
				
			||||
	struct super_block * sb;
 | 
				
			||||
	struct m_inode * dir =current->pwd;
 | 
				
			||||
	struct m_inode * olddir  =NULL;
 | 
				
			||||
	while(1){
 | 
				
			||||
		olddir = dir;
 | 
				
			||||
		if (olddir==current->root)
 | 
				
			||||
			break;
 | 
				
			||||
		if (!dir->i_zone[0])
 | 
				
			||||
			return -1;
 | 
				
			||||
		if(!(bh = bread(dir->i_dev,dir->i_zone[0])))//获得i节点指向的数据块
 | 
				
			||||
			return -1;
 | 
				
			||||
		de = (struct dir_entry *) bh->b_data;
 | 
				
			||||
		int find = de->inode;
 | 
				
			||||
		if (!(dir = iget(dir->i_dev,(de+1)->inode))){//dir更新并判断错误
 | 
				
			||||
			return -1;
 | 
				
			||||
		}
 | 
				
			||||
		if(!(bh = bread(dir->i_dev,dir->i_zone[0])))//获得i节点指向的数据块
 | 
				
			||||
			return -1;
 | 
				
			||||
		de = (struct dir_entry *) bh->b_data;
 | 
				
			||||
		//printk("dir_size is %d \n",dir->i_size);
 | 
				
			||||
		int flag = 1;
 | 
				
			||||
		int f1=1,f2=1;
 | 
				
			||||
		//printk("find inode is %d\n",find);
 | 
				
			||||
		while(flag<=(dir->i_size/16)){
 | 
				
			||||
		//	printk("de->i_node is %d de->name is %s \n",de->inode,de->name);
 | 
				
			||||
			if(de->inode==find){
 | 
				
			||||
				//printk("%s\n",de->name);
 | 
				
			||||
				strcpy(s[num--],de->name);
 | 
				
			||||
				//printk(" file is  %s \n",s[num+1]);
 | 
				
			||||
				break;
 | 
				
			||||
			}
 | 
				
			||||
			f1++;
 | 
				
			||||
			if (f1>1024/16){
 | 
				
			||||
				bh = bread(dir->i_dev,dir->i_zone[f2++]);
 | 
				
			||||
				de = (struct dir_entry *) bh->b_data;
 | 
				
			||||
			}
 | 
				
			||||
			de++;
 | 
				
			||||
			flag++;
 | 
				
			||||
		}
 | 
				
			||||
	}
 | 
				
			||||
	size_t len = 0;
 | 
				
			||||
	char *buf1;
 | 
				
			||||
	for(i=num+1;i<=19;i++){
 | 
				
			||||
		printk("/%s",s[i]);
 | 
				
			||||
	}
 | 
				
			||||
	printk("\n");
 | 
				
			||||
	//printk("getcwd is %s \n",buf1);
 | 
				
			||||
	//return NULL;
 | 
				
			||||
}
 | 
				
			||||
int sys_getdents(unsigned int fd,struct linux_dirent *dirp,unsigned int count){
 | 
				
			||||
	return -1;
 | 
				
			||||
}
 | 
				
			||||
int sys_execve2(){
 | 
				
			||||
	return -1;
 | 
				
			||||
}
 | 
				
			||||
					Loading…
					
					
				
		Reference in new issue