Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2379 → Rev 2380

/branches/fs/uspace/fs/stadir.c
0,0 → 1,140
/* This file contains the code for performing four system calls relating to
* status and directories.
*/
 
/* Methods:
* do_chdir: perform the CHDIR system call
* do_stat: perform the STAT system call
* do_fstat: perform the FSTAT system call
*/
 
 
#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);
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;
}
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;
}
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;
}
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));
}
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;
}