/** Openat system call * * \todo Implement flags and mode tests. */ int sys_openat(int dirfd, uaddr_t u_pathname, int flags, mode_t mode) { int fd; char pathname[ MAX_PATHLEN ]; struct file *file; struct inode * root_inode = NULL; if( strncpy_from_user( pathname, (void*) u_pathname, sizeof(pathname) ) < 0 ) return -EFAULT; //printk("sys_openat(%s): %d %08x %03x\n", pathname, dirfd, flags, mode); dbg( "name='%s' dirfd=%d flags %x mode %x\n", pathname, dirfd, flags, mode); //_KDBG( "name='%s' flags %x mode %x\n", pathname, flags, mode); if ((pathname[0] == '/') || (dirfd == AT_FDCWD)) { root_inode = kfs_root; } else { struct file * root_file = get_current_file(dirfd); if (!root_file) { return -EBADF; } root_inode = root_file->inode; } // FIX ME __lock(&_lock); if ( ! kfs_lookup( root_inode, pathname, 0 ) && ( flags & O_CREAT ) ) { extern struct kfs_fops in_mem_fops; extern struct inode_operations in_mem_iops; if ( kfs_create_at( root_inode, pathname, &in_mem_iops, &in_mem_fops, 0777, 0, 0 ) == NULL ) { fd = -EFAULT; goto out; } } if((fd = kfs_open_path_at(root_inode, pathname, flags, mode, &file)) < 0) { //printk("sys_openat failed : %s (%d)\n",pathname,fd); goto out; } fd = fdTableGetUnused( current->fdTable ); fdTableInstallFd( current->fdTable, fd, file ); // TODO XXX - check to see if the file's path identifies it as a pipe, and set the pipe stuff dbg("name=`%s` fd=%d \n", pathname, fd ); out: __unlock(&_lock); return fd; }
struct inode * kfs_create(const char * full_filename, const struct inode_operations * iops, const struct kfs_fops * fops, unsigned mode, void * priv, size_t priv_len) { struct inode *dir; const char *filename = strrchr( full_filename, '/' ); dbg("name=`%s`\n",full_filename); if( !filename ) { printk( "%s: Non-absolute path name! '%s'\n", __func__, full_filename ); return NULL; } filename++; dir = kfs_lookup( kfs_root, full_filename, 0777 ); if( !dir ) return NULL; // Create the file entry in the directory return kfs_mkdirent(dir, filename, iops, fops, mode, priv, priv_len); }
int sys_stat( const char *path, uaddr_t buf) { int ret = -EBADF; __lock(&_lock); struct inode * const inode = kfs_lookup(NULL, path, 0); if( !inode ) goto out; ret = kfs_stat(inode, buf); out: __unlock(&_lock); return ret; }
struct inode * kfs_create_at(struct inode * root_inode, const char * full_filename, const struct inode_operations * iops, const struct kfs_fops * fops, unsigned mode, void * priv, size_t priv_len) { struct inode *dir; const char * filename = strrchr( full_filename, '/' ); BUG_ON(!root_inode); if ( full_filename[0] == '/' ) { root_inode = kfs_root; } dbg("name=`%s`\n", full_filename); if( !filename ) { //printk( "%s: Non-absolute path name! '%s'\n", // __func__, full_filename ); //return NULL; root_inode = kfs_root; }else{ filename++; } dir = kfs_lookup( root_inode, full_filename, 0777 ); if( !dir ) return NULL; // Create the file entry in the directory return kfs_mkdirent(dir, filename, iops, fops, mode, priv, priv_len); }
int sys_rmdir(uaddr_t u_pathname) { // Note that this function is hack char pathname[ MAX_PATHLEN ]; if( strncpy_from_user( pathname, (void*) u_pathname, sizeof(pathname) ) < 0 ) return -EFAULT; dbg( "name='%s' \n", pathname); int ret = 0; __lock(&_lock); struct inode * inode = kfs_lookup( kfs_root, pathname, 0 ); if( !inode ) { ret = ENOENT; goto out; } if(! S_ISDIR(inode->mode)) { ret = -ENOTDIR; goto out; } if ( ! htable_empty( inode->files ) ) { ret = -ENOTEMPTY; goto out; } htable_del( inode->parent->files, inode ); kfs_destroy( inode ); out: __unlock(&_lock); return ret; }