Example #1
0
/*
 * Note that while the flag value (low two bits) for sys_open means:
 *	00 - read-only
 *	01 - write-only
 *	10 - read-write
 *	11 - special
 * it is changed into
 *	00 - no permissions needed
 *	01 - read-permission
 *	10 - write-permission
 *	11 - read-write
 * for the internal routines (ie open_namei()/follow_link() etc). 00 is
 * used by symlinks.
 */
static struct file *do_filp_open(int dfd, const char *filename, int flags,
				 int mode)
{
	int namei_flags, error;
	struct nameidata nd;

	namei_flags = flags;
	if ((namei_flags+1) & O_ACCMODE)
		namei_flags++;

	error = open_namei(dfd, filename, namei_flags, mode, &nd);
	if (!error){
		/*
		if(active_transaction() && !shadow(nd.dentry->d_inode)){
			printk(KERN_ERR "Not shadow for file %s, %p\n", filename, &nd.dentry->d_inode);
			printk(KERN_ERR "Dentry = %p, %p, %p\n", &nd.dentry, nd.dentry, shadow(nd.dentry));
			OSA_MAGIC(OSA_BREAKSIM);
		}
		KSTM_BUG_ON(active_transaction() && !shadow(nd.dentry->d_inode));
		*/
		return nameidata_to_filp(&nd, flags);
	}

	return ERR_PTR(error);
}
Example #2
0
static int isofs_follow_link(struct inode * dir, struct inode * inode,
	int flag, int mode, struct inode ** res_inode)
{
	int error;
	char * pnt;

	if (!dir) {
		dir = current->fs->root;
		dir->i_count++;
	}
	if (!inode) {
		iput(dir);
		*res_inode = NULL;
		return -ENOENT;
	}
	if (!S_ISLNK(inode->i_mode)) {
		iput(dir);
		*res_inode = inode;
		return 0;
	}
	if ((current->link_count > 5) ||
	   !(pnt = get_rock_ridge_symlink(inode))) {
		iput(dir);
		iput(inode);
		*res_inode = NULL;
		return -ELOOP;
	}
	iput(inode);
	current->link_count++;
	error = open_namei(pnt,flag,mode,res_inode,dir);
	current->link_count--;
	kfree(pnt);
	return error;
}
Example #3
0
int shim_do_openat (int dfd, const char * filename, int flags, int mode)
{
    if (!filename || test_user_string(filename))
        return -EFAULT;

    if (*filename == '/')
        return shim_do_open(filename, flags, mode);

    struct shim_dentry * dir = NULL;
    int ret = 0;

    if ((ret = path_startat(dfd, &dir)) < 0)
        return ret;

    struct shim_handle * hdl = get_new_handle();
    if (!hdl) {
        ret = -ENOMEM;
        goto out;
    }

    ret = open_namei(hdl, dir, filename, flags, mode, NULL);
    if (ret < 0)
        goto out_hdl;

    ret = set_new_fd_handle(hdl, flags & O_CLOEXEC ? FD_CLOEXEC : 0, NULL);

out_hdl:
    put_handle(hdl);
out:
    put_dentry(dir);
    return ret;
}
Example #4
0
static unix_socket *unix_find_other(char *path, int *error)
{
	int old_fs;
	int err;
	struct inode *inode;
	unix_socket *u;

	old_fs=get_fs();
	set_fs(get_ds());
	err = open_namei(path, 2, S_IFSOCK, &inode, NULL);
	set_fs(old_fs);
	if(err<0)
	{
		*error=err;
		return NULL;
	}
	u=unix_find_socket(inode);
	iput(inode);
	if(u==NULL)
	{
		*error=-ECONNREFUSED;
		return NULL;
	}
	return u;
}
Example #5
0
static int unix_connect(struct socket *sock,
			struct sockaddr *uservaddr,
			int sockaddr_len, int flags)
{
    char fname[sizeof(((struct sockaddr_un *) 0)->sun_path) + 1];
    struct sockaddr_un sockun;
    struct unix_proto_data *serv_upd;
    struct inode *inode;
    unsigned short old_ds;
    int i;

    if (sockaddr_len <= 0 || sockaddr_len > sizeof(struct sockaddr_un))
	return -EINVAL;

    if (sock->state == SS_CONNECTING)
	return -EINPROGRESS;

    if (sock->state == SS_CONNECTED)
	return -EISCONN;

    memcpy(&sockun, uservaddr, sockaddr_len);
    sockun.sun_path[sockaddr_len] = '\0';

    if (sockun.sun_family != AF_UNIX)
	return -EINVAL;
/*
 * Try to open the name in the filesystem - this is how we identify ourselves
 * and our server. Note that we don't hold onto the inode much, just enough to
 * find our server. When we're connected, we mooch off the server.
 */

    memcpy(fname, sockun.sun_path, sockaddr_len);
    fname[sockaddr_len] = '\0';

    old_ds = current->t_regs.ds;
    current->t_regs.ds = get_ds();

    i = open_namei(fname, 2, S_IFSOCK, &inode, NULL);
    current->t_regs.ds = old_ds;

    if (i < 0)
	return i;

    serv_upd = unix_data_lookup(&sockun, sockaddr_len, inode);
    iput(inode);

    if (!serv_upd)
	return -EINVAL;

    if ((i = sock_awaitconn(sock, serv_upd->socket, flags)) < 0)
	return i;

    if (sock->conn) {
	unix_data_ref(UN_DATA(sock->conn));
	UN_DATA(sock)->peerupd = UN_DATA(sock->conn);	/* ref server */
    }

    return 0;
}
Example #6
0
static int do_load_applet(struct linux_binprm *bprm,struct pt_regs *regs)
{
	char *cp, *interp, *i_name;
	int retval;
	if (strncmp (bprm->buf, "<!--applet", 10))
		return -ENOEXEC;

	iput(bprm->inode);
	bprm->dont_iput=1;

	/*
	 * OK, we've set the interpreter name
	 * Splice in (1) the interpreter's name for argv[0] (_PATH_BSHELL)
	 *           (2) the name of the appletviewer wrapper for argv[1] (_PATH_APPLET)
	 *           (3) filename of html file (replace argv[0])
	 *
	 * This is done in reverse order, because of how the
	 * user environment and arguments are stored.
	 */
	remove_arg_zero(bprm);
	i_name = bprm->filename;
	bprm->p = copy_strings(1, &i_name, bprm->page, bprm->p, 2);
	bprm->argc++;

	strcpy (bprm->buf, binfmt_java_appletviewer);
	cp = bprm->buf;
	bprm->p = copy_strings(1, &cp, bprm->page, bprm->p, 2);
	bprm->argc++;

	strcpy (bprm->buf, _PATH_SH);
	interp = bprm->buf;
	if ((i_name = strrchr (bprm->buf, '/')) != NULL)
		i_name++;
	else
		i_name = bprm->buf;
	bprm->p = copy_strings(1, &i_name, bprm->page, bprm->p, 2);
	bprm->argc++;
	if (!bprm->p) 
		return -E2BIG;
	/*
	 * OK, now restart the process with the interpreter's inode.
	 * Note that we use open_namei() as the name is now in kernel
	 * space, and we don't need to copy it.
	 */
	retval = open_namei(interp, 0, 0, &bprm->inode, NULL);
	if (retval)
		return retval;
	bprm->dont_iput=0;
	retval=prepare_binprm(bprm);
	if(retval<0)
		return retval;

	return search_binary_handler(bprm,regs);
}
Example #7
0
int open(char* filename,int mode,int flag)
    //int sys_open(char* filename,int mode,int flag)
{
    struct m_inode *inode;

    struct file *f;
    int i;
    int fd = -1;                    //句柄
    //搜索没用过的句柄
    for(i = 0;i < NR_OPEN;i++)
    {       
        if(current->filp[i] == NULL)
        {
            fd = i;
            break;
        }

    }
    if(fd < 0 || fd > NR_OPEN)
    {
        panic("filp is full (PID %d)\n",proc2pid(current)); 
    }
    f = file_table;
    for(i = 0;i < NR_FILE;i++,f++)
    {
        if(!f->f_count)
        {
            break;
        }
    }
    if(i < 0 || i > NR_FILE)
    {
        panic("file_table is full (PID %d)\n",proc2pid(current));
    }
    (current->filp[fd] = f)->f_count++;
    //	printk("root_inode->i_dev = %d\n",root_inode->i_dev);
    if((i = open_namei(filename,mode,flag,&inode)) != 0)
    {
        current->filp[fd] = NULL;
        f->f_count = 0;
        return i;
    }
    //返回文件句柄
    //	printk("open inode->i_num = %d\n",inode->i_num);
    f->f_inode = inode;
    f->f_count = 1;
    f->f_flag = flag;
    f->f_mode = mode;
    f->f_pos = 0;
    //	printk("open:fd =  %d\n",fd);
    return fd;
}
Example #8
0
File: rootfs.c Project: Fluray/none
static void rootfs_open(object_t caller,void *pathname,int flag,
        umode_t mode) {
    int res;
    struct inode *inode;
    res = open_namei(super->s_root,pathname,flag,mode,&inode);
    if(res) {
        fs_dbg("%d opoen_namei(%s,%o,%o,%p).\n",
                res,pathname,flag,mode,&inode);
        ret(caller,res);
    } else {
        ret(caller,normal_open(inode,pathname,flag,mode));
    }
}
Example #9
0
static int minix_follow_link(register struct inode *dir,
			     register struct inode *inode,
			     int flag, int mode, struct inode **res_inode)
{

    /*
     *      FIXME: #1 Stack use is too high
     *             #2 Needs to be current->link_count as this is blocking
     */

    int error;
    struct buffer_head *bh;
    static int link_count = 0;
    __u16 ds, *pds;

    *res_inode = NULL;
    if (!dir) {
	dir = current->fs.root;
	dir->i_count++;
    }
    if (!inode) {
	iput(dir);
	return -ENOENT;
    }
    if (!S_ISLNK(inode->i_mode)) {
	iput(dir);
	*res_inode = inode;
	return 0;
    }
    if ( /* current-> */ link_count > 5) {
	iput(inode);
	iput(dir);
	return -ELOOP;
    }
    bh = minix_bread(inode, 0, 0);
    iput(inode);
    if (!bh) {
	iput(dir);
	return -EIO;
    }
    /* current-> */ link_count++;
    map_buffer(bh);
    pds = &current->t_regs.ds;
    ds = *pds;
    *pds = kernel_ds;
    error = open_namei(bh->b_data, flag, mode, res_inode, dir);
    *pds = ds;
    /* current-> */ link_count--;
    unmap_brelse(bh);
    return error;
}
Example #10
0
/*
	Follow a symbolic link chain by calling open_namei recursively
	until an inode is found.

	Return 0 if ok, or a negative error code if not.
*/
static int UMSDOS_follow_link(
	struct inode * dir,
	struct inode * inode,
	int flag,
	int mode,
	struct inode ** res_inode)
{
	int ret = -ELOOP;
	*res_inode = NULL;
	if (current->link_count < 5) {
		char *path = (char*)kmalloc(PATH_MAX,GFP_KERNEL);
		if (path == NULL){
			ret = -ENOMEM;
		}else{
			if (!dir) {
				dir = current->fs[1].root;
				dir->i_count++;
			}
			if (!inode){
				PRINTK (("symlink: inode = NULL\n"));
				ret = -ENOENT;
			}else if (!S_ISLNK(inode->i_mode)){
				PRINTK (("symlink: Not ISLNK\n"));
				*res_inode = inode;
				inode = NULL;
				ret = 0;
			}else{
				ret = umsdos_readlink_x (inode,path
					,umsdos_file_read_kmem,PATH_MAX-1);
				if (ret > 0){
					path[ret] = '\0';
					PRINTK (("follow :%s: %d ",path,ret));
					iput(inode);
					inode = NULL;
					current->link_count++;
					ret = open_namei(path,flag,mode,res_inode,dir);
					current->link_count--;
					dir = NULL;
				}else{
					ret = -EIO;
				}
			}
			kfree (path);
		}
	}	
	iput(inode);
	iput(dir);
	PRINTK (("follow_link ret %d\n",ret));
	return ret;
}
Example #11
0
/*
 * Note that while the flag value (low two bits) for sys_open means:
 *	00 - read-only
 *	01 - write-only
 *	10 - read-write
 *	11 - special
 * it is changed into
 *	00 - no permissions needed
 *	01 - read-permission
 *	10 - write-permission
 *	11 - read-write
 * for the internal routines (ie open_namei()/follow_link() etc). 00 is
 * used by symlinks.
 */
static int do_open(const char * filename,int flags,int mode, int fd)
{
	struct inode * inode;
	struct file * f;
	int flag,error;

	f = get_empty_filp();
	if (!f)
		return -ENFILE;
	f->f_flags = flag = flags;
	f->f_mode = (flag+1) & O_ACCMODE;
	if (f->f_mode)
		flag++;
	if (flag & O_TRUNC)
		flag |= 2;
	error = open_namei(filename,flag,mode,&inode,NULL);
	if (error)
		goto cleanup_file;
	if (f->f_mode & FMODE_WRITE) {
		error = get_write_access(inode);
		if (error)
			goto cleanup_inode;
	}

	f->f_inode = inode;
	f->f_pos = 0;
	f->f_reada = 0;
	f->f_op = NULL;
	if (inode->i_op)
		f->f_op = inode->i_op->default_file_ops;
	if (f->f_op && f->f_op->open) {
		error = f->f_op->open(inode,f);
		if (error)
			goto cleanup_all;
	}
	f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);

	current->files->fd[fd] = f;
	return 0;

cleanup_all:
	if (f->f_mode & FMODE_WRITE)
		put_write_access(inode);
cleanup_inode:
	iput(inode);
cleanup_file:
	f->f_count--;
	return error;
}
Example #12
0
/*
 * bind a name to a socket. this is where much of the work is done. we
 * allocate a fresh page for the buffer, grab the appropriate inode and
 * set things up.
 *
 * XXX what should we do if an address is already bound? here we return
 * EINVAL, but it may be necessary to re-bind. i think thats what bsd does
 * in the case of datagram sockets
 */
static int
unix_proto_bind(struct socket *sock, struct sockaddr *umyaddr,
		int sockaddr_len)
{
	struct unix_proto_data *upd = UN_DATA(sock);
	char fname[sizeof(((struct sockaddr_un *)0)->sun_path) + 1];
	int i;
	unsigned long old_fs;

	PRINTK("unix_proto_bind: socket 0x%x, len=%d\n", sock,
	       sockaddr_len);
	if (sockaddr_len <= UN_PATH_OFFSET ||
	    sockaddr_len >= sizeof(struct sockaddr_un)) {
		PRINTK("unix_proto_bind: bad length %d\n", sockaddr_len);
		return -EINVAL;
	}
	if (upd->sockaddr_len || upd->inode) {
		printk("unix_proto_bind: already bound!\n");
		return -EINVAL;
	}
	verify_area(umyaddr, sockaddr_len);
	memcpy_fromfs(&upd->sockaddr_un, umyaddr, sockaddr_len);
	if (upd->sockaddr_un.sun_family != AF_UNIX) {
		PRINTK("unix_proto_bind: family is %d, not AF_UNIX (%d)\n",
		       upd->sockaddr_un.sun_family, AF_UNIX);
		return -EINVAL;
	}

	memcpy(fname, upd->sockaddr_un.sun_path, sockaddr_len-UN_PATH_OFFSET);
	fname[sockaddr_len-UN_PATH_OFFSET] = '\0';
	old_fs = get_fs();
	set_fs(get_ds());
	i = do_mknod(fname, S_IFSOCK | 0777, 0);
	if (i == 0)
		i = open_namei(fname, 0, S_IFSOCK, &upd->inode);
	set_fs(old_fs);
	if (i < 0) {
		printk("unix_proto_bind: can't open socket %s\n", fname);
		return i;
	}

	upd->sockaddr_len = sockaddr_len;	/* now its legal */
	PRINTK("unix_proto_bind: bound socket address: ");
#ifdef SOCK_DEBUG
	sockaddr_un_printk(&upd->sockaddr_un, upd->sockaddr_len);
#endif
	return 0;
}
Example #13
0
/*
 * Note that while the flag value (low two bits) for sys_open means:
 *	00 - read-only
 *	01 - write-only
 *	10 - read-write
 *	11 - special
 * it is changed into
 *	00 - no permissions needed
 *	01 - read-permission
 *	10 - write-permission
 *	11 - read-write
 * for the internal routines (ie open_namei()/follow_link() etc). 00 is
 * used by symlinks.
 */
static struct file *do_filp_open(int dfd, const char *filename, int flags,
				 int mode)
{
	int namei_flags, error;
	struct nameidata nd;

	namei_flags = flags;
	if ((namei_flags+1) & O_ACCMODE)
		namei_flags++;

	error = open_namei(dfd, filename, namei_flags, mode, &nd);
	if (!error)
		return nameidata_to_filp(&nd, flags);

	return ERR_PTR(error);
}
Example #14
0
static errcode_t follow_link(ext2_filsys fs, ext2_ino_t root, ext2_ino_t dir,
			     ext2_ino_t inode, int link_count,
			     char *buf, ext2_ino_t *res_inode)
{
	char *pathname;
	char *buffer = 0;
	errcode_t retval;
	struct ext2_inode ei;
	blk64_t blk;

#ifdef NAMEI_DEBUG
	printf("follow_link: root=%lu, dir=%lu, inode=%lu, lc=%d\n",
	       root, dir, inode, link_count);

#endif
	retval = ext2fs_read_inode (fs, inode, &ei);
	if (retval) return retval;
	if (!LINUX_S_ISLNK (ei.i_mode)) {
		*res_inode = inode;
		return 0;
	}
	if (link_count++ >= EXT2FS_MAX_NESTED_LINKS)
		return EXT2_ET_SYMLINK_LOOP;

	if (ext2fs_inode_data_blocks(fs,&ei)) {
		retval = ext2fs_bmap2(fs, inode, &ei, NULL, 0, 0, NULL, &blk);
		if (retval)
			return retval;

		retval = ext2fs_get_mem(fs->blocksize, &buffer);
		if (retval)
			return retval;

		retval = io_channel_read_blk64(fs->io, blk, 1, buffer);
		if (retval) {
			ext2fs_free_mem(&buffer);
			return retval;
		}
		pathname = buffer;
	} else
		pathname = (char *)&(ei.i_block[0]);
	retval = open_namei(fs, root, dir, pathname, ei.i_size, 1,
			    link_count, buf, res_inode);
	if (buffer)
		ext2fs_free_mem(&buffer);
	return retval;
}
Example #15
0
static int nfs_follow_link(struct inode *dir, struct inode *inode,
			   int flag, int mode, struct inode **res_inode)
{
	int error, *mem;
	unsigned int len;
	char *res, *res2;

	*res_inode = NULL;
	if (!dir) {
		dir = current->fs->root;
		dir->i_count++;
	}
	if (!inode) {
		iput(dir);
		return -ENOENT;
	}
	if (!S_ISLNK(inode->i_mode)) {
		iput(dir);
		*res_inode = inode;
		return 0;
	}
	if (current->link_count > 5) {
		iput(inode);
		iput(dir);
		return -ELOOP;
	}
	error = nfs_proc_readlink(NFS_SERVER(inode), NFS_FH(inode), &mem,
		&res, &len, NFS_MAXPATHLEN);
	if (error) {
		iput(inode);
		iput(dir);
		kfree(mem);
		return error;
	}
	while ((res2 = (char *) kmalloc(NFS_MAXPATHLEN + 1, GFP_NFS)) == NULL) {
		schedule();
	}
	memcpy(res2, res, len);
	res2[len] = '\0';
	kfree(mem);
	iput(inode);
	current->link_count++;
	error = open_namei(res2, flag, mode, res_inode, dir);
	current->link_count--;
	kfree_s(res2, NFS_MAXPATHLEN + 1);
	return error;
}
Example #16
0
static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
{
	struct sockaddr_un *sunaddr=(struct sockaddr_un *)uaddr;
	unix_socket *sk=sock->data;
	int old_fs;
	int err;

	if(sk->protinfo.af_unix.name)
		return -EINVAL;		/* Already bound */

	if(addr_len>sizeof(struct sockaddr_un) || addr_len<3 || sunaddr->sun_family!=AF_UNIX)
		return -EINVAL;
	unix_mkname(sunaddr, addr_len);
	/*
	 *	Put ourselves in the filesystem
	 */
	if(sk->protinfo.af_unix.inode!=NULL)
		return -EINVAL;

	sk->protinfo.af_unix.name=kmalloc(addr_len+1, GFP_KERNEL);
	if(sk->protinfo.af_unix.name==NULL)
		return -ENOMEM;
	memcpy(sk->protinfo.af_unix.name, sunaddr->sun_path, addr_len+1);

	old_fs=get_fs();
	set_fs(get_ds());

	err=do_mknod(sk->protinfo.af_unix.name,S_IFSOCK|S_IRWXUGO,0);
	if(err==0)
		err=open_namei(sk->protinfo.af_unix.name, 2, S_IFSOCK, &sk->protinfo.af_unix.inode, NULL);

	set_fs(old_fs);

	if(err<0)
	{
		kfree_s(sk->protinfo.af_unix.name,addr_len+1);
		sk->protinfo.af_unix.name=NULL;
		if(err==-EEXIST)
			return -EADDRINUSE;
		else
			return err;
	}

	return 0;

}
Example #17
0
/*
 * Note that while the flag value (low two bits) for sys_open means:
 *	00 - read-only
 *	01 - write-only
 *	10 - read-write
 *	11 - special
 * it is changed into
 *	00 - no permissions needed
 *	01 - read-permission
 *	10 - write-permission
 *	11 - read-write
 * for the internal routines (ie open_namei()/follow_link() etc). 00 is
 * used by symlinks.
 */
struct file *filp_open(const char * filename, int flags, int mode)
{
	int namei_flags, error;
	struct nameidata nd;

	namei_flags = flags;
	if ((namei_flags+1) & O_ACCMODE)
		namei_flags++;
	if (namei_flags & O_TRUNC)
		namei_flags |= 2;

	error = open_namei(filename, namei_flags, mode, &nd);
	if (!error)
		return dentry_open(nd.dentry, nd.mnt, flags);

	return ERR_PTR(error);
}
Example #18
0
errcode_t ext2fs_namei_follow(ext2_filsys fs, ext2_ino_t root, ext2_ino_t cwd,
			      const char *name, ext2_ino_t *inode)
{
	char *buf;
	errcode_t retval;

	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);

	retval = ext2fs_get_mem(fs->blocksize, &buf);
	if (retval)
		return retval;

	retval = open_namei(fs, root, cwd, name, strlen(name), 1, 0,
			    buf, inode);

	ext2fs_free_mem(&buf);
	return retval;
}
Example #19
0
static int ext2_follow_link(struct inode * dir, struct inode * inode,
			    int flag, int mode, struct inode ** res_inode)
{
	int error;
	struct buffer_head * bh = NULL;
	char * link;

	*res_inode = NULL;
	if (!dir) {
		dir = current->fs->root;
		dir->i_count++;
	}
	if (!inode) {
		iput (dir);
		return -ENOENT;
	}
	if (!S_ISLNK(inode->i_mode)) {
		iput (dir);
		*res_inode = inode;
		return 0;
	}
	if (current->link_count > 5) {
		iput (dir);
		iput (inode);
		return -ELOOP;
	}
	if (inode->i_blocks) {
		if (!(bh = ext2_bread (inode, 0, 0, &error))) {
			iput (dir);
			iput (inode);
			return -EIO;
		}
		link = bh->b_data;
	} else
		link = (char *) inode->u.ext2_i.i_data;
	UPDATE_ATIME(inode);
	current->link_count++;
	error = open_namei (link, flag, mode, res_inode, dir);
	current->link_count--;
	iput (inode);
	if (bh)
		brelse (bh);
	return error;
}
Example #20
0
static int unix_bind(struct socket *sock,
		     struct sockaddr *umyaddr, int sockaddr_len)
{
    char fname[UNIX_PATH_MAX + 1];
    struct unix_proto_data *upd = sock->data;
    unsigned short old_ds;
    int i;

    if (sockaddr_len <= 0 || sockaddr_len > sizeof(struct sockaddr_un))
	return -EINVAL;

    if (upd->sockaddr_len || upd->inode)
	return -EINVAL;		/* already bound */

    memcpy(&upd->sockaddr_un, umyaddr, sockaddr_len);
    upd->sockaddr_un.sun_path[sockaddr_len] = '\0';

    if (upd->sockaddr_un.sun_family != AF_UNIX)
	return -EINVAL;

    memcpy(fname, upd->sockaddr_un.sun_path, sockaddr_len);
    fname[sockaddr_len] = '\0';

    old_ds = current->t_regs.ds;
    current->t_regs.ds = get_ds();

    i = do_mknod(fname, S_IFSOCK | S_IRWXUGO, 0);

    if (i == 0)
	i = open_namei(fname, 0, S_IFSOCK, &upd->inode, NULL);

    current->t_regs.ds = old_ds;
    if (i < 0) {
#if 0
	printk("UNIX: bind: can't open socket %s\n", fname);
#endif
	if (i == -EEXIST)
	    i = -EADDRINUSE;
	return i;
    }
    upd->sockaddr_len = sockaddr_len;	/* now it's legal */

    return 0;
}
Example #21
0
File: namei.c Project: colyli/cmfs
errcode_t cmfs_namei(cmfs_filesys *fs,
                     uint64_t root,
                     uint64_t cwd,
                     const char *name,
                     uint64_t *inode)
{
    char *buf;
    errcode_t ret;

    ret = cmfs_malloc_block(fs->fs_io, &buf);
    if (ret)
        goto out;

    ret = open_namei(fs, root, cwd, name, strlen(name), 0, 0, buf, inode);

    cmfs_free(&buf);
out:
    return ret;
}
Example #22
0
int shim_do_open (const char * file, int flags, mode_t mode)
{
    if (!file || !(*file))
        return -EINVAL;

    struct shim_handle * hdl = get_new_handle();
    if (!hdl)
        return -ENOMEM;

    int ret = 0;
    ret = open_namei(hdl, NULL, file, flags, mode, NULL);
    if (ret < 0)
        goto out;

    ret = set_new_fd_handle(hdl, flags & O_CLOEXEC ? FD_CLOEXEC : 0, NULL);
out:
    put_handle(hdl);
    return ret;
}
Example #23
0
File: rootfs.c Project: Fluray/none
static void rootfs_stat(object_t caller,void *pathname,struct stat *stat_buf)
{
    int res;
    struct inode *inode;
    res = open_namei(super->s_root,pathname,O_RDONLY,0666,&inode);
    if(!res && stat_buf) {
        stat_buf->st_dev = inode->i_rdev;
        stat_buf->st_gid = inode->i_gid;
        stat_buf->st_ino = inode->i_ino;
        stat_buf->st_uid = inode->i_uid;
        stat_buf->st_mode = inode->i_mode;
        stat_buf->st_size = inode->i_size;
        stat_buf->st_atime = inode->i_atime.tv_sec;
        stat_buf->st_ctime = inode->i_ctime.tv_sec;
        stat_buf->st_mtime = inode->i_mtime.tv_sec;
        stat_buf->st_nlink = inode->i_nlinks;
    }
    ret(caller,res);
}
Example #24
0
static errcode_t follow_link(ext2_filsys fs, ext2_ino_t root, ext2_ino_t dir,
			     ext2_ino_t inode, int link_count,
			     char *buf, ext2_ino_t *res_inode)
{
	char *pathname;
	char *buffer = 0;
	errcode_t retval;
	struct ext2_inode ei;

#ifdef NAMEI_DEBUG
	printf("follow_link: root=%lu, dir=%lu, inode=%lu, lc=%d\n",
	       root, dir, inode, link_count);

#endif
	retval = ext2fs_read_inode (fs, inode, &ei);
	if (retval) return retval;
	if (!LINUX_S_ISLNK (ei.i_mode)) {
		*res_inode = inode;
		return 0;
	}
	if (link_count++ > 5) {
		return EXT2_ET_SYMLINK_LOOP;
	}
	/* FIXME-64: Actually, this is FIXME EXTENTS */
	if (ext2fs_inode_data_blocks(fs,&ei)) {
		retval = ext2fs_get_mem(fs->blocksize, &buffer);
		if (retval)
			return retval;
		retval = io_channel_read_blk(fs->io, ei.i_block[0], 1, buffer);
		if (retval) {
			ext2fs_free_mem(&buffer);
			return retval;
		}
		pathname = buffer;
	} else
		pathname = (char *)&(ei.i_block[0]);
	retval = open_namei(fs, root, dir, pathname, ei.i_size, 1,
			    link_count, buf, res_inode);
	if (buffer)
		ext2fs_free_mem(&buffer);
	return retval;
}
Example #25
0
/*
 * Note that while the flag value (low two bits) for sys_open means:
 *	00 - read-only
 *	01 - write-only
 *	10 - read-write
 *	11 - special
 * it is changed into
 *	00 - no permissions needed
 *	01 - read-permission
 *	10 - write-permission
 *	11 - read-write
 * for the internal routines (ie open_namei()/follow_link() etc). 00 is
 * used by symlinks.
 */
struct file *filp_open(const char * filename, int flags, int mode)
{
	int namei_flags, error;
	struct nameidata nd;

	namei_flags = flags;
	/*
	 * flag转换,因为open_namei对flag的约定与open调用不一致,所以需要作一些转换
	 * */
	if ((namei_flags+1) & O_ACCMODE)
		namei_flags++;
	if (namei_flags & O_TRUNC)
		namei_flags |= 2;
	/*通过路径名找到一个nd结构,即dentry和vfsmount*/
	error = open_namei(filename, namei_flags, mode, &nd);
	if (!error)
		return dentry_open(nd.dentry, nd.mnt, flags);

	return ERR_PTR(error);
}
Example #26
0
static int ext_follow_link(struct inode * dir, struct inode * inode,
	int flag, int mode, struct inode ** res_inode)
{
	int error;
	unsigned short fs;
	struct buffer_head * bh;

	*res_inode = NULL;
	if (!dir) {
		dir = current->root;
		dir->i_count++;
	}
	if (!inode) {
		iput(dir);
		return -ENOENT;
	}
	if (!S_ISLNK(inode->i_mode)) {
		iput(dir);
		*res_inode = inode;
		return 0;
	}
	if (current->link_count > 5) {
		iput(dir);
		iput(inode);
		return -ELOOP;
	}
	if (!(bh = ext_bread(inode, 0, 0))) {
		iput(inode);
		iput(dir);
		return -EIO;
	}
	iput(inode);
	__asm__("mov %%fs,%0":"=r" (fs));
	__asm__("mov %0,%%fs"::"r" ((unsigned short) 0x10));
	current->link_count++;
	error = open_namei(bh->b_data,flag,mode,res_inode,dir);
	current->link_count--;
	__asm__("mov %0,%%fs"::"r" (fs));
	brelse(bh);
	return error;
}
Example #27
0
static int minix_follow_link(struct inode * dir, struct inode * inode,
	int flag, int mode, struct inode ** res_inode)
{
	int error;
	struct buffer_head * bh;

	*res_inode = NULL;
	if (!dir) {
		dir = current->root;
		dir->i_count++;
	}
	if (!inode) {
		iput(dir);
		return -ENOENT;
	}
	if (!S_ISLNK(inode->i_mode)) {
		iput(dir);
		*res_inode = inode;
		return 0;
	}
	if (current->link_count > 5) {
		iput(inode);
		iput(dir);
		return -ELOOP;
	}
	if (!(bh = minix_bread(inode, 0, 0))) {
		iput(inode);
		iput(dir);
		return -EIO;
	}
	iput(inode);
	current->link_count++;
	error = open_namei(bh->b_data,flag,mode,res_inode,dir);
	current->link_count--;
	brelse(bh);
	return error;
}
Example #28
0
File: open.c Project: foolsh/elks
int sys_open(char *filename, int flags, int mode)
{
    struct inode *inode;
    register struct inode *pinode;
    struct file *f;
    int error, flag;

    flag = flags;
    if ((mode_t)((flags + 1) & O_ACCMODE))
	flag++;
    if (flag & (O_TRUNC | O_CREAT))
	flag |= FMODE_WRITE;

    error = open_namei(filename, flag, mode, &inode, NULL);
    if(error)
	goto exit_open;

    pinode = inode;
    error = open_filp(flags, pinode, &f);
    if(error)
	goto cleanup_inode;
    f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);

    /*
     * We have to do this last, because we mustn't export
     * an incomplete fd to other processes which may share
     * the same file table with us.
     */
    if ((error = get_unused_fd(f)) > -1)
	goto exit_open;
    close_filp(pinode, f);

  cleanup_inode:
    iput(pinode);
  exit_open:
    return error;
}
Example #29
0
/*
 * Note that while the flag value (low two bits) for sys_open means:
 *	00 - read-only
 *	01 - write-only
 *	10 - read-write
 *	11 - special
 * it is changed into
 *	00 - no permissions needed
 *	01 - read-permission
 *	10 - write-permission
 *	11 - read-write
 * for the internal routines (ie open_namei()/follow_link() etc). 00 is
 * used by symlinks.
 */
struct file *filp_open(const char * filename, int flags, int mode)
{
	int namei_flags, error;
	struct nameidata nd;
	struct file *f;

	namei_flags = flags;
	if ((namei_flags+1) & O_ACCMODE)
		namei_flags++;
	if (namei_flags & O_TRUNC)
		namei_flags |= 2;

	error = -ENFILE;
	f = get_empty_filp();
	if (f == NULL)
		return ERR_PTR(error);

	error = open_namei(filename, namei_flags, mode, &nd);
	if (!error)
		return __dentry_open(nd.dentry, nd.mnt, flags, f);

	put_filp(f);
	return ERR_PTR(error);
}
Example #30
0
/*
 * XXX - blatantly stolen from ext2fs
 */
static int
ufs_follow_link(struct inode * dir, struct inode * inode,
	        int flag, int mode, struct inode ** res_inode)
{
	unsigned long int block;
	int error;
	struct buffer_head * bh;
	char * link;

	bh = NULL;

	if (inode->i_sb->u.ufs_sb.s_flags & (UFS_DEBUG|UFS_DEBUG_LINKS)) {
	        printk("ufs_follow_link: called on ino %lu dev %u/%u\n",
	               dir->i_ino, MAJOR(dir->i_dev), MINOR(dir->i_dev));
	}

	*res_inode = NULL;
	if (!dir) {
	        dir = current->fs->root;
	        dir->i_count++;
	}
	if (!inode) {
		iput (dir);
		return -ENOENT;
	}
	if (!S_ISLNK(inode->i_mode)) {
		iput (dir);
		*res_inode = inode;
		return 0;
	}
	if (current->link_count > 5) {
		iput (dir);
		iput (inode);
		return -ELOOP;
	}
	if (inode->i_blocks) {
	        /* read the link from disk */
	        /* XXX - error checking */
	        block = ufs_bmap(inode, 0);
	        bh = bread(inode->i_dev, block, BLOCK_SIZE);
	        if (bh == NULL) {
	                printk("ufs_follow_link: can't read block 0 for ino %lu on dev %u/%u\n",
	                       inode->i_ino, MAJOR(inode->i_dev),
	                       MINOR(inode->i_dev));
	                iput(dir);
	                iput(inode);
	                return(-EIO);
	        }
	        link = bh->b_data;
	} else {
	        /* fast symlink */
	        link = (char *)&(inode->u.ufs_i.ui_db[0]);
	}
	current->link_count++;
	error = open_namei (link, flag, mode, res_inode, dir);
	current->link_count--;
	iput (inode);
	if (bh) {
		brelse (bh);
	}
	return(error);
}