/*
* 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 stadir.c
* @brief This file contains the code for performing four system calls relating to
* status and directories.
*/
#include "fs.h"
#include "stat.h"
#include "file.h"
#include "fproc.h"
#include "inode.h"
#include "param.h"
static int change(inode_t **iip, char *name_ptr, int len);
static int stat_inode(inode_t *rip, filp_t *fil_ptr, char *user_addr);
/**
* Perform the CHDIR system call
*/
int do_chdir()
{
/* Perform the chdir(file_name) system call */
int r;
r
= change
(&fp
->fp_workdir
, file_name
, strlen(file_name
)+1);
return r;
}
/**
* Execute changing the current directory
*/
int change(inode_t **iip, char *name_ptr, int len)
{
/*
* iip: pointer to the inode pointer for the dir
* name_ptr: pointer to the directory name to change to
* len: length of the directory name string
*/
/* Do the actual work for chdir() and chroot(). */
inode_t *rip;
register int r;
r = OK;
/* Try to open the new directory. */
if (fetch_name(name_ptr, len) != OK)
return err_code;
if ((rip = eat_path(user_path)) == NIL_INODE)
return err_code;
/* It must be a directory and also be searchable. */
if ((rip->i_mode & I_TYPE) != I_DIRECTORY)
r = FS_ENOTDIR;
/* If error, return inode. */
if (r != OK) {
put_inode(rip);
return r;
}
/* Everything is OK. Make the change. */
put_inode(*iip); /* release the old directory */
*iip = rip; /* acquire the new one */
return OK;
}
/**
* Perform the STAT system call
*/
int do_stat()
{
/* Perform the stat(name, buf) system call. */
register inode_t *rip;
register int r;
/* Both stat() and fstat() use the same routine to do the real work. That
* routine expects an inode, so acquire it temporarily.
*/
if (fetch_name
(file_name
, strlen(file_name
)+1) != OK
)
return err_code;
if ((rip = eat_path(user_path)) == NIL_INODE)
return err_code;
r = stat_inode(rip, NIL_FILP, fp->buffer); /* actually do the work.*/
put_inode(rip); /* release the inode */
return r;
}
/**
* Perform the FSTAT system call
*/
int do_fstat()
{
/* Perform the fstat(fd, buf) system call. */
register filp_t *rfilp;
/* Is the file descriptor valid? */
if ((rfilp = get_filp(fd)) == NIL_FILP)
return err_code;
if (rfilp->filp_ino == NIL_INODE)
return FS_ENOENT;
return(stat_inode(rfilp->filp_ino, NIL_FILP, fp->buffer));
}
/**
* Execute the actual STAT operation
*/
int stat_inode(register inode_t *rip, filp_t *fil_ptr, char *user_addr)
{
/*
* rip: pointer to inode to stat
* fil_ptr: filp pointer, supplied by 'fstat'
* user_addr: user space address where stat buf goes
*/
/* Common code for stat and fstat system calls. */
stat_t statbuf;
/* Fill in the statbuf struct. */
statbuf.st_ino = rip->i_num;
statbuf.st_mode = rip->i_mode;
statbuf.st_nlink = rip->i_nlinks & BYTE;
statbuf.st_size = rip->i_size;
/* Copy infomations to userspace. */
memcpy(user_addr
, &statbuf
, sizeof(statbuf
));
return OK;
}
/**
* }
*/