/*
* Copyright (c) 1987,1997, Prentice Hall
* All rights reserved.
*
* Redistribution and use of the MINIX operating system in source and
* binary forms, with or without modification, are permitted provided
* that the following conditions are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* - Neither the name of Prentice Hall nor the names of the software
* authors or contributors may be used to endorse or promote
* products derived from this software without specific prior
* written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS, AUTHORS, AND
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL PRENTICE HALL OR ANY AUTHORS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** @addtogroup FileSystemImpl
* @{
*/
/**
* @file open.c
* @brief This file contains the procedures for opening, closing, and seeking on files.
*/
#include "fs.h"
#include "block.h"
#include "file.h"
#include "fproc.h"
#include "inode.h"
#include "param.h"
/**
* Perform the OPEN system call
*/
int do_open()
{
/* Perform the open(file_name) system call */
int r;
register inode_t *rip;
filp_t *fil_ptr;
r
= fetch_name
(file_name
, strlen(file_name
)+1);
if (r != OK)
return err_code; /* name was bad */
/* See if file descriptor and filp slots are available. */
if ( (r = get_fd(0, &fd, &fil_ptr)) != OK)
return r;
/* Scan path name. */
if ( (rip = eat_path(user_path)) == NIL_INODE)
return err_code;
/* Claim the file descriptor and filp slot and fill them in. */
fp->fp_filp[fd] = fil_ptr;
fil_ptr->filp_count = 1;
fil_ptr->filp_ino = rip;
fil_ptr->filp_flags = R_BIT;
return fd;
}
/**
* Perform the CLOSE system call
*/
int do_close()
{
/* Perform the close(fd) system call. */
register filp_t *rfilp;
register inode_t *rip;
/* First locate the inode that belongs to the file descriptor */
if ( (rfilp = get_filp(fd)) == NIL_FILP)
return err_code;
rip = rfilp->filp_ino; /* 'rip' points to the inode */
if (--rfilp->filp_count == 0) {
put_inode(rip);
}
fp->fp_filp[fd] = NIL_FILP;
return OK;
}
/**
* Perform the SEEK system call
*/
int do_lseek()
{
/* Perform the seek(ls_fd, offset, whence) system call. */
register filp_t *rfilp;
register offset_t pos, new_pos;
/* Check to see if the file descriptor is valid. */
if ( (rfilp = get_filp(fd)) == NIL_FILP)
return err_code;
/* The value of 'whence' determines the start position to use. */
switch(whence) {
case 0: pos = 0;
break;
case 1: pos = rfilp->filp_pos;
break;
case 2: pos = rfilp->filp_ino->i_size;
break;
default: return FS_EINVAL;
}
/* Check for overflow. */
if (((long)offset > 0) && ((long)(pos + offset) < (long)pos))
return FS_EINVAL;
if (((long)offset < 0) && ((long)(pos + offset) > (long)pos))
return FS_EINVAL;
new_pos = pos + offset;
/* Check for setting behind the end. */
if ((new_pos) > rfilp->filp_ino->i_size) {
pos = rfilp->filp_ino->i_size;
}
else if (new_pos < 0) {
pos = 0;
}
else {
pos = new_pos;
}
rfilp->filp_pos = pos;
return pos;
}
/**
* }
*/