Ejemplo n.º 1
0
int
pipe(int pfd[2])
{
	int r;
	struct Fd *fd0, *fd1;
	void *va;

	// allocate the file descriptor table entries
	if ((r = fd_find_unused(&fd0)) < 0
	    || (r = sys_page_alloc(0, fd0, PTE_P|PTE_W|PTE_U|PTE_SHARE)) < 0)
		goto err;

	if ((r = fd_find_unused(&fd1)) < 0
	    || (r = sys_page_alloc(0, fd1, PTE_P|PTE_W|PTE_U|PTE_SHARE)) < 0)
		goto err1;

	// allocate the pipe structure as first data page in both
	va = fd2data(fd0);
	if ((r = sys_page_alloc(0, va, PTE_P|PTE_W|PTE_U|PTE_SHARE)) < 0)
		goto err2;
	if ((r = sys_page_map(0, va, 0, fd2data(fd1), PTE_P|PTE_W|PTE_U|PTE_SHARE)) < 0)
		goto err3;

	// set up fd structures
	fd0->fd_dev_id = devpipe.dev_id;
	fd0->fd_omode = O_RDONLY;

	fd1->fd_dev_id = devpipe.dev_id;
	fd1->fd_omode = O_WRONLY;

	if (debug)
		cprintf("[%08x] pipecreate %08x\n", thisenv->env_id, vpt[PGNUM(va)]);

	pfd[0] = fd2num(fd0);
	pfd[1] = fd2num(fd1);
	return 0;

    err3:
	sys_page_unmap(0, va);
    err2:
	sys_page_unmap(0, fd1);
    err1:
	sys_page_unmap(0, fd0);
    err:
	return r;
}
Ejemplo n.º 2
0
int
opencons(void)
{
	int r;
	struct Fd* fd;

	if ((r = fd_find_unused(&fd)) < 0)
		return r;
	if ((r = sys_page_alloc(0, fd, PTE_P|PTE_U|PTE_W|PTE_SHARE)) < 0)
		return r;
	fd->fd_dev_id = devcons.dev_id;
	fd->fd_omode = O_RDWR;
	return fd2num(fd);
}
Ejemplo n.º 3
0
// Open a file (or directory).
//
// Returns:
// 	The file descriptor index on success
// 	-E_BAD_PATH if the path is too long (>= MAXPATHLEN)
//	-E_BAD_PATH if an intermediate path component is not a directory
//	-E_MAX_FD if no more file descriptors
//	-E_NOT_FOUND if the file (or a path component) was not found
//	(and others)
int
open(const char *path, int mode)
{
	// Find an unused file descriptor page using fd_find_unused
	// and allocate a page there (PTE_P|PTE_U|PTE_W|PTE_SHARE).
	//
	// LAB 5: Your code here
    int r;
    struct Fd *fd;
    if((r = fd_find_unused(&fd)) < 0 || 
    (r = sys_page_alloc(0, fd, PTE_P|PTE_U|PTE_W|PTE_SHARE)) < 0)
        goto err1;
	// Check the pathname.  Error if too long.
	// Use path_walk to find the corresponding directory entry.
	// If '(mode & O_CREAT) == 0' (Exercise 4),
	//   Return -E_NOT_FOUND if the file is not found.
	//   Otherwise, use inode_open to open the inode.
	// If '(mode & O_CREAT) != 0' (Exercise 7),
	//   Create the file if it doesn't exist yet.
	//   Allocate a new inode, initialize its fields, and
	//   reference that inode from the new directory entry.
	//   Flush any blocks you change.
	// Directories can be opened, but only as read-only:
	// return -E_IS_DIR if '(mode & O_ACCMODE) != O_RDONLY'.
	//
	// Check for errors.  On error, make sure you clean up any
	// allocated objects.
	//
	// The root directory is a special case -- if you aren't careful,
	// you will deadlock when the root directory is opened.  (Why?)
	//
	// LAB 5: Your code here.
    int i;
    for(i = 0; i < MAXNAMELEN && path[i]; i++); 
    if(i == MAXNAMELEN)
    {
        r = -E_BAD_PATH;
        goto err2;
    }
    struct Inode *dirino;
    struct Direntry *de;
    if((r = path_walk(path, &dirino, &de, mode & O_CREAT)))
        goto err2;
    struct Inode *fileino;
    
    if(!(mode & O_CREAT))
    {
        if(de == &super->s_root)
            fileino = dirino;
        else if((r = inode_open(de->de_inum, &fileino)) < 0)
            goto err3;
        
        if(fileino->i_ftype == FTYPE_DIR && (
           mode & O_ACCMODE) != O_RDONLY)
        {
            r = -E_IS_DIR;
            goto err4;
        }
    }
    else 
    {
        if((r = inode_alloc(&fileino)) < 0)
            goto err3;
        fileino->i_ftype = FTYPE_REG;
        fileino->i_refcount = 1;
        fileino->i_size = 0;
        memset(&fileino->i_direct, 0, NDIRECT * sizeof (blocknum_t));
        de->de_inum = fileino->i_inum;
        bcache_ipc(fileino, BCREQ_FLUSH); 
        bcache_ipc(dirino, BCREQ_FLUSH); 
    }
	// If '(mode & O_TRUNC) != 0' and the open mode is not read-only,
	// set the file's length to 0.  Flush any blocks you change.
	//
	// LAB 5: Your code here (Exercise 8).
    if((mode & O_TRUNC))
    {
        inode_set_size(fileino, 0);
    }        

	// The open has succeeded.
	// Fill in all parts of the 'fd' appropriately.  Use 'devfile.dev_id'.
	// Copy the file's pathname into 'fd->fd_file.open_path' to improve
	// error messages later.
	// You must account for the open file reference in the inode as well.
	// Clean up any open inodes.
	//
	// LAB 5: Your code here (Exercise 4).
    fd->fd_dev_id = devfile.dev_id;
    fd->fd_offset = 0;
    fd->fd_omode = mode;
    fd->fd_file.inum = fileino->i_inum; 
    strcpy(fd->fd_file.open_path, path);
    fileino->i_opencount++;
    inode_close(dirino);
    inode_close(fileino);
    return fd2num(fd);

err4:
    inode_close(fileino);
err3:
    inode_close(dirino);
err2:
    sys_page_unmap(thisenv->env_id, fd);
err1:
    return r;
}