Subversion Repositories shark

Rev

Rev 3 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 pj 1
 
1063 tullio 2
/*
3
 * This program is free software; you can redistribute it and/or modify
4
 * it under the terms of the GNU General Public License as published by
5
 * the Free Software Foundation; either version 2 of the License, or
6
 * (at your option) any later version.
7
 *
8
 * This program is distributed in the hope that it will be useful,
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
 * GNU General Public License for more details.
12
 *
13
 * You should have received a copy of the GNU General Public License
14
 * along with this program; if not, write to the Free Software
15
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
 *
17
 */
18
 
2 pj 19
#include <fs/types.h>
20
#include <fs/errno.h>
21
#include <fs/task.h>
22
#include <fs/maccess.h>
23
#include <fs/stat.h>
24
#include <fs/fcntl.h>
25
#include <fs/mount.h>
26
 
27
#include "fsconst.h"
28
#include "file.h"
29
#include "dentry.h"
30
#include "inode.h"
31
#include "fileop.h"
32
#include "inodeop.h"
33
#include "super.h"
34
#include "fs.h"
35
 
36
#include "debug.h"
37
 
38
 
39
/*
40
  Example of how the code is expanded in system with/without
41
  memory protection.
42
 
43
  If DUMMY_MACCESS is defined:
44
 
45
  char *pathname;
46
  int len;
47
 
48
  len=1;
49
  if ((!len)||len>MAXSIZE) return -EVERIFY;
50
  pathname=userpathname;
51
  ...
52
 
53
 
54
  if DUMMY_MACCESS is NOT defined:
55
 
56
  char pathname[MAXSIZE];
57
  int len;
58
 
59
  len=verifyreadnolen(userpathanme);
60
  if ((!len)||len>MAXSIZE) return -EVERIFY;
61
  memcpyfromuser(pathname,userpathname);
62
  ...
63
 
64
*/
65
 
66
/* PS: open() e opendir() potrebbero condividere codice! */
67
 
68
int k_open(char *upathname, int oflag, int mode)
69
{
70
  declare_buffer(char,pathname,MAXPATHNAME);
71
  int len;
72
  struct file   *f;
73
  struct dentry *d;
74
  int           ret,res,createflag;
75
  __pid_t       pid;
76
 
77
  call_to_fs();
78
 
79
  printk0("k_open: START");
80
  pid=__get_pid();
81
 
82
  len=__verify_read_nolen((char*)upathname);
83
  if ((!len)||(len>MAXPATHNAMELEN)) return_from_fs(-EVERIFY);
84
  __copy_from_user(pathname,upathname,len+1);
85
 
86
  printk0("k_open: verifing memory... done");
87
 
88
  /* flags not supported */
89
  /* O_NOCTTY is ignored */
90
  if (oflag&O_DSYNC||
91
      oflag&O_NOCTTY||
92
      oflag&O_NONBLOCK||
93
      oflag&O_RSYNC||
94
      oflag&O_SYNC) {
95
    return_from_fs(-EACCES);
96
  }
97
 
98
  /* O_TRUNC wiht O_RDONLY not permitted! */
99
  if ((oflag&O_RDONLY)&&(oflag&O_TRUNC)) return_from_fs(-EACCES);
100
 
101
  printk0("k_open: checking flags... done");
102
 
103
  if (oflag&O_CREAT) {
104
    if (oflag&O_EXCL) createflag=DENTRY_MUSTCREATE;
105
    else createflag=DENTRY_CANCREATE;
106
  } else createflag=DENTRY_NOCREATE;
107
 
108
 
109
  d=find_dentry_from_ext(cwden_ptr(pid),(char *)pathname,&createflag);
110
  if (d==NULL) {
111
    printk0("k_open: can't find/create directory entry");
112
    if (createflag&DENTRY_EXIST) return_from_fs(-EEXIST);
113
    return_from_fs(-ENOENT);
114
  }
115
 
116
  if (__S_ISDIR(d->d_inode->i_st.st_mode)) {
117
    if (oflag&O_WRONLY||oflag&O_RDWR)
118
      /* can't write on a directory */
119
      return_from_fs(-EISDIR);
120
  }
121
 
122
  /* check for read-only filesystem */
123
  if (!(d->d_sb->sb_mopts.flags&MOUNT_FLAG_RW)) {
124
    if (oflag&O_WRONLY||oflag&O_RDWR||oflag&O_TRUNC) {
125
      /* NB: O_CREAT va testata prima della find_dentry() */
126
      unlock_dentry(d);      
127
      return_from_fs(-EROFS);
128
    }
129
  }
130
 
131
  printk0("k_open: find dir entry... done");
132
 
133
  f=get_file(d->d_inode);
134
  if (f==NULL) {
135
    unlock_dentry(d);
136
    return_from_fs(-ENFILE);
137
  }
138
 
139
  printk0("k_open: getting system file entry... done");
140
 
141
  if (createflag&DENTRY_CREATED)
142
    d->d_inode->i_st.st_mode=(mode&__ALLPERMS)|__S_IFREG;
143
 
144
  f->f_dentry=d;
145
  f->f_op=d->d_inode->i_op->default_file_ops;
146
  f->f_pos=0;
147
  f->f_flag_isdir=__S_ISDIR(d->d_inode->i_st.st_mode);
148
 
149
  ret=get_fd(pid,f);
150
  if (ret==-1) {
151
    free_file(f);
152
    unlock_dentry(d);
153
    return_from_fs(-EMFILE);
154
  }
155
  *fildesfflags_ptr(pid,ret)=oflag;
156
 
157
  printk0("k_open: getting file descriptor... done");
158
 
159
  if (oflag&O_TRUNC&&!(createflag&DENTRY_CREATED)) {
160
    struct inode *in=file_ptr(pid,ret)->f_dentry->d_inode;
161
    /* acquire write lock on inode's file */
162
    __rwlock_wrlock(&in->i_lock);
163
    /* truncate the file */
164
    in->i_op->truncate(in,0);      
165
    /* release write lock on inode's file */
166
    __rwlock_wrunlock(&in->i_lock);
167
    printk0("k_open: file truncation... done");
168
  }
169
 
170
  res=f->f_op->open(f->f_dentry->d_inode,f);
171
  if (res!=0) {
172
    free_fd(pid,ret);
173
    free_file(f);
174
    unlock_dentry(d);
175
    return_from_fs(res);
176
  }
177
 
178
  printk0("k_open: called proper filesystem open... done");
179
 
180
  printk0("k_open: END");
181
  return_from_fs(ret);
182
}
183