// Open a file (or directory).
//
// Returns:
// 	The file descriptor index on success
// 	-E_BAD_PATH if the path is too long (>= MAXPATHLEN)
// 	< 0 for other errors.
int
open(const char *path, int mode)
{
	// Find an unused file descriptor page using fd_alloc.
	// Then send a file-open request to the file server.
	// Include 'path' and 'omode' in request,
	// and map the returned file descriptor page
	// at the appropriate fd address.
	// FSREQ_OPEN returns 0 on success, < 0 on failure.
	//
	// (fd_alloc does not allocate a page, it just returns an
	// unused fd address.  Do you need to allocate a page?)
	//
	// Return the file descriptor index.
	// If any step after fd_alloc fails, use fd_close to free the
	// file descriptor.

	// LAB 5: Your code here.

	struct Fd* retval;
	int r = fd_alloc(&retval);
	if(r<0) return r;

	fsipcbuf.open.req_omode = mode;
	strcpy(fsipcbuf.open.req_path, path);
	r = fsipc(FSREQ_OPEN, retval);
	if (r<0) {
		fd_close(retval, 0);
		return r;	
	}
	return fd2num(retval);

	// panic("open not implemented");
}
Exemple #2
0
// Open a file (or directory).
//
// Returns:
// 	The file descriptor index on success
// 	-E_BAD_PATH if the path is too long (>= MAXPATHLEN)
// 	< 0 for other errors.
int
open(const char *path, int mode)
{
	// Find an unused file descriptor page using fd_alloc.
	// Then send a file-open request to the file server.
	// Include 'path' and 'omode' in request,
	// and map the returned file descriptor page
	// at the appropriate fd address.
	// FSREQ_OPEN returns 0 on success, < 0 on failure.
	//
	// (fd_alloc does not allocate a page, it just returns an
	// unused fd address.  Do you need to allocate a page?)
	//
	// Return the file descriptor index.
	// If any step after fd_alloc fails, use fd_close to free the
    struct Fd *f    = NULL;
    int r   = 0;

    if (!path)
        return -E_INVAL;

    if((r=fd_alloc(&f))<0)
        return r;

	strcpy(fsipcbuf.open.req_path, path);
	fsipcbuf.open.req_omode = mode;

    if ((r=fsipc(FSREQ_OPEN, f))<0) {
        fd_close(f, 0);
        return r;
    }
    return fd2num(f);
}
Exemple #3
0
// Open a file (or directory),
// returning the file descriptor index on success, < 0 on failure.
int
open(const char *path, int mode)
{
	// Find an unused file descriptor page using fd_alloc.
	// Then send a message to the file server to open a file
	// using a function in fsipc.c.
	// (fd_alloc does not allocate a page, it just returns an
	// unused fd address.  Do you need to allocate a page?  Look
	// at fsipc.c if you aren't sure.)
	// Then map the file data (you may find fmap() helpful).
	// Return the file descriptor index.
	// If any step fails, use fd_close to free the file descriptor.

	// LAB 5: Your code here.
	
	int r;
	struct Fd *fd;

	if ((r = fd_alloc(&fd)) < 0)
		return r;
	
	if ((r = fsipc_open(path, mode, fd)) < 0){
		fd_close(fd, 0);	
		return r;
	}

	if ((r = fmap(fd, 0, fd->fd_file.file.f_size) ) < 0){
		fd_close(fd, 0);	
		return r;
	}	
	
	return fd2num(fd);
}
Exemple #4
0
// Open a file (or directory).
//
// Returns:
// 	The file descriptor index on success
// 	-E_BAD_PATH if the path is too long (>= MAXPATHLEN)
// 	< 0 for other errors.
int
open(const char *path, int mode)
{
	// Find an unused file descriptor page using fd_alloc.
	// Then send a file-open request to the file server.
	// Include 'path' and 'omode' in request,
	// and map the returned file descriptor page
	// at the appropriate fd address.
	// FSREQ_OPEN returns 0 on success, < 0 on failure.
	//
	// (fd_alloc does not allocate a page, it just returns an
	// unused fd address.  Do you need to allocate a page?)
	//
	// Return the file descriptor index.
	// If any step after fd_alloc fails, use fd_close to free the
	// file descriptor.

	// LAB 5: Your code here.
	struct Fd *fd;
	int r;

	if((r = fd_alloc(&fd)) < 0)
		return r;
	strcpy(fsipcbuf.open.req_path, path);
        fsipcbuf.open.req_omode = mode;
        ipc_send(envs[1].env_id, FSREQ_OPEN, &fsipcbuf, PTE_P | PTE_W | PTE_U);
        if((r = ipc_recv(NULL, fd, NULL))<0)
		return r;
	return fd2num(fd);
	panic("open not implemented");
}
Exemple #5
0
int
pipe(int pfd[2])
{
	int r;
	struct Fd *fd0, *fd1;
	void *va;

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

	if ((r = fd_alloc(&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", env->env_id, vpt[VPN(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;
}
Exemple #6
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);
}
Exemple #7
0
int
opencons(void)
{
	int r;
	struct Fd *fd;

	if ((r = fd_alloc(&fd)) < 0)
		return r;
	if ((r = syscall_mem_alloc(0, (u_int)fd, PTE_V|PTE_R|PTE_LIBRARY)) < 0)
		return r;
	fd->fd_dev_id = devcons.dev_id;
	fd->fd_omode = O_RDWR;
	return fd2num(fd);
}
Exemple #8
0
// Frees file descriptor 'fd' by closing the corresponding file
// and unmapping the file descriptor page.
// If 'must_exist' is 0, then fd can be a closed or nonexistent file
// descriptor; the function will return 0 and have no other effect.
// If 'must_exist' is 1, then fd_close returns -E_INVAL when passed a
// closed or nonexistent file descriptor.
// Returns 0 on success, < 0 on error.
int
fd_close(struct Fd *fd, bool must_exist)
{
	struct Fd *fd2;
	struct Dev *dev;
	int r;
	if ((r = fd_lookup(fd2num(fd), &fd2)) < 0
	    || fd != fd2)
		return (must_exist ? r : 0);
	if ((r = dev_lookup(fd->fd_dev_id, &dev)) >= 0)
		r = (*dev->dev_close)(fd);
	// Make sure fd is unmapped.  Might be a no-op if
	// (*dev->dev_close)(fd) already unmapped it.
	(void) sys_page_unmap(0, fd);
	return r;
}
Exemple #9
0
// Open a file (or directory).
//
// Returns:
// 	The file descriptor index on success
// 	-E_BAD_PATH if the path is too long (>= MAXPATHLEN)
// 	< 0 for other errors.
int
open(const char *path, int mode)
{
	// Find an unused file descriptor page using fd_alloc.
	// Then send a file-open request to the file server.
	// Include 'path' and 'omode' in request,
	// and map the returned file descriptor page
	// at the appropriate fd address.
	// FSREQ_OPEN returns 0 on success, < 0 on failure.
	//
	// (fd_alloc does not allocate a page, it just returns an
	// unused fd address.  Do you need to allocate a page?)
	//
	// Return the file descriptor index.
	// If any step after fd_alloc fails, use fd_close to free the
	// file descriptor.

	// LAB 5: Your code here.
	//panic("open not implemented");
	int result;
	struct Fd *fd_instance;
	
	if(strlen(path) >= MAXPATHLEN)
	{
		cprintf("open() error: path is too long");
		return -E_BAD_PATH;
	}
	
	if((result=fd_alloc(&fd_instance)) < 0)
	{
		return result;
	}
	
	strcpy(fsipcbuf.open.req_path, path);
	fsipcbuf.open.req_omode=mode;
	
	if((result=fsipc(FSREQ_OPEN, (void *)fd_instance)) < 0) 
	{
		fd_close(fd_instance, 0);
		
		return result;
	}
	else
	{		
		return fd2num(fd_instance);
	}
}
Exemple #10
0
// Open a file (or directory).
//
// Returns:
// 	The file descriptor index on success
// 	-E_BAD_PATH if the path is too long (>= MAXPATHLEN)
// 	< 0 for other errors.
int
open(const char *path, int mode)
{
	// Find an unused file descriptor page using fd_alloc.
	// Then send a file-open request to the file server.
	// Include 'path' and 'omode' in request,
	// and map the returned file descriptor page
	// at the appropriate fd address.
	// FSREQ_OPEN returns 0 on success, < 0 on failure.
	//
	// (fd_alloc does not allocate a page, it just returns an
	// unused fd address.  Do you need to allocate a page?)
	//
	// Return the file descriptor index.
	// If any step after fd_alloc fails, use fd_close to free the
	// file descriptor.

	// LAB 5: Your code here.
  int r;
  struct Fd *fd;

  r = fd_alloc(&fd);
  if (r < 0) return r;

        // DO NOT ALLOCATE !!
        //r = sys_page_alloc(0, fd, PTE_U|PTE_W|PTE_P);
        //if (r < 0) goto out;

  if (strlen(path) >= MAXPATHLEN)
    return -E_BAD_PATH;
  strcpy(fsipcbuf.open.req_path, path);
  fsipcbuf.open.req_omode = mode;
  r = fsipc(FSREQ_OPEN, fd);
  if (r < 0) goto out;
  return fd2num(fd);
out:
  assert(fd_close(fd, 0) == 0);
  return r;
}
// Open a file (or directory).
//
// Returns:
// 	The file descriptor index on success
// 	-E_BAD_PATH if the path is too long (>= MAXPATHLEN)
// 	< 0 for other errors.
int
open(const char *path, int mode)
{
	// Find an unused file descriptor page using fd_alloc.
	// Then send a file-open request to the file server.
	// Include 'path' and 'omode' in request,
	// and map the returned file descriptor page
	// at the appropriate fd address.
	// FSREQ_OPEN returns 0 on success, < 0 on failure.
	//
	// (fd_alloc does not allocate a page, it just returns an
	// unused fd address.  Do you need to allocate a page?)
	//
	// Return the file descriptor index.
	// If any step after fd_alloc fails, use fd_close to free the
	// file descriptor.

	if (strlen(path) > MAXPATHLEN)
		return -E_BAD_PATH;

	struct Fd *fd;
	int r;
	if ((r < fd_alloc(&fd)) < 0)
		return r;

        strcpy(fsipcbuf.open.req_path, path);
        fsipcbuf.open.req_omode = mode;

        if ((r = fsipc(FSREQ_OPEN, fd)) < 0) {
		fd_close(fd, 0);
                return r;
	}

	return fd2num(fd);

	panic("open not implemented");
}
char*
fd2data(struct Fd *fd)
{
	return INDEX2DATA(fd2num(fd));
}
Exemple #13
0
// Return the file descriptor data pointer for a 'struct Fd'.
//
char *
fd2data(struct Fd *fd)
{
	int num = fd2num(fd);
	return (char *) (FDDATA + num * PGSIZE);
}
Exemple #14
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;
}