Subversion Repositories HelenOS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2380 konopa 1
/* This file contains the code for performing four system calls relating to
2
 * status and directories.
3
 */
4
 
5
/* Methods:
6
 * do_chdir:  perform the CHDIR system call
7
 * do_stat:   perform the STAT system call
8
 * do_fstat:  perform the FSTAT system call
9
 */
10
 
11
 
12
#include "fs.h"
13
#include "stat.h"
14
#include "file.h"
15
#include "fproc.h"
16
#include "inode.h"
17
#include "param.h"
18
 
19
 
20
static int change(inode_t **iip, char *name_ptr, int len);
21
static int stat_inode(inode_t *rip, filp_t *fil_ptr, char *user_addr);
22
 
23
int do_chdir()
24
{
25
 
26
    /* Perform the chdir(file_name) system call */
27
    int r;
28
 
29
    r = change(&fp->fp_workdir, file_name, strlen(file_name)+1);
30
 
31
    return r;
32
}
33
 
34
int change(inode_t **iip, char *name_ptr, int len)
35
{
36
 
37
    /*
38
     * iip:     pointer to the inode pointer for the dir
39
     * name_ptr:    pointer to the directory name to change to
40
     * len:     length of the directory name string
41
     */
42
 
43
    /* Do the actual work for chdir() and chroot(). */
44
 
45
    inode_t *rip;
46
    register int r;
47
 
48
    r = OK;
49
 
50
    /* Try to open the new directory. */
51
    if (fetch_name(name_ptr, len) != OK)
52
        return err_code;
53
 
54
    if ((rip = eat_path(user_path)) == NIL_INODE)
55
        return err_code;
56
 
57
    /* It must be a directory and also be searchable. */
58
    if ((rip->i_mode & I_TYPE) != I_DIRECTORY)
59
        r = FS_ENOTDIR;
60
 
61
    /* If error, return inode. */
62
    if (r != OK) {
63
        put_inode(rip);
64
        return r;
65
    }
66
 
67
    /* Everything is OK.  Make the change. */
68
    put_inode(*iip);    /* release the old directory */
69
    *iip = rip;     /* acquire the new one */
70
 
71
    return OK;
72
}
73
 
74
int do_stat()
75
{
76
 
77
    /* Perform the stat(name, buf) system call. */
78
 
79
    register inode_t *rip;
80
    register int r;
81
 
82
    /* Both stat() and fstat() use the same routine to do the real work.  That
83
     * routine expects an inode, so acquire it temporarily.
84
     */
85
 
86
    if (fetch_name(file_name, strlen(file_name)+1) != OK)
87
        return err_code;
88
 
89
    if ((rip = eat_path(user_path)) == NIL_INODE)
90
        return err_code;
91
 
92
    r = stat_inode(rip, NIL_FILP, fp->buffer); /* actually do the work.*/
93
    put_inode(rip);     /* release the inode */
94
 
95
    return r;
96
}
97
 
98
int do_fstat()
99
{
100
 
101
    /* Perform the fstat(fd, buf) system call. */
102
 
103
    register filp_t *rfilp;
104
 
105
 
106
    /* Is the file descriptor valid? */
107
    if ((rfilp = get_filp(fd)) == NIL_FILP)
108
        return err_code;
109
 
110
    if (rfilp->filp_ino == NIL_INODE)
111
        return FS_ENOENT;
112
 
113
    return(stat_inode(rfilp->filp_ino, NIL_FILP, fp->buffer));
114
}
115
 
116
int stat_inode(register inode_t *rip, filp_t *fil_ptr, char *user_addr)
117
{  
118
 
119
    /*
120
     * rip:         pointer to inode to stat
121
     * fil_ptr:     filp pointer, supplied by 'fstat'
122
     * user_addr:   user space address where stat buf goes
123
     */
124
 
125
    /* Common code for stat and fstat system calls. */
126
 
127
    stat_t statbuf;
128
 
129
    /* Fill in the statbuf struct. */
130
    statbuf.st_ino = rip->i_num;
131
    statbuf.st_mode = rip->i_mode;
132
    statbuf.st_nlink = rip->i_nlinks & BYTE;
133
    statbuf.st_size = rip->i_size;
134
 
135
    /* Copy infomations to userspace. */
136
    memcpy(user_addr, &statbuf, sizeof(statbuf));
137
 
138
    return OK;
139
}
140