~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/ken/nami.c

Version: ~ [ linux-5.1-rc1 ] ~ [ linux-5.0.3 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.30 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.107 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.164 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.176 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.136 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.63 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.39.4 ] ~ [ linux-2.6.38.8 ] ~ [ linux-2.6.37.6 ] ~ [ linux-2.6.36.4 ] ~ [ linux-2.6.35.14 ] ~ [ linux-2.6.34.15 ] ~ [ linux-2.6.33.20 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 #include "../param.h"
  2 #include "../inode.h"
  3 #include "../user.h"
  4 #include "../systm.h"
  5 #include "../buf.h"
  6 
  7 /*
  8  * Convert a pathname into a pointer to
  9  * an inode. Note that the inode is locked.
 10  *
 11  * func = function called to get next char of name
 12  *      &uchar if name is in user space
 13  *      &schar if name is in system space
 14  * flag = 0 if name is sought
 15  *      1 if name is to be created
 16  *      2 if name is to be deleted
 17  */
 18 namei(func, flag)
 19 int (*func)();
 20 {
 21         register struct inode *dp;
 22         register c;
 23         register char *cp;
 24         int eo, *bp;
 25 
 26         /*
 27          * If name starts with '/' start from
 28          * root; otherwise start from current dir.
 29          */
 30 
 31         dp = u.u_cdir;
 32         if((c=(*func)()) == '/')
 33                 dp = rootdir;
 34         iget(dp->i_dev, dp->i_number);
 35         while(c == '/')
 36                 c = (*func)();
 37         if(c == '\0' && flag != 0) {
 38                 u.u_error = ENOENT;
 39                 goto out;
 40         }
 41 
 42 cloop:
 43         /*
 44          * Here dp contains pointer
 45          * to last component matched.
 46          */
 47 
 48         if(u.u_error)
 49                 goto out;
 50         if(c == '\0')
 51                 return(dp);
 52 
 53         /*
 54          * If there is another component,
 55          * dp must be a directory and
 56          * must have x permission.
 57          */
 58 
 59         if((dp->i_mode&IFMT) != IFDIR) {
 60                 u.u_error = ENOTDIR;
 61                 goto out;
 62         }
 63         if(access(dp, IEXEC))
 64                 goto out;
 65 
 66         /*
 67          * Gather up name into
 68          * users' dir buffer.
 69          */
 70 
 71         cp = &u.u_dbuf[0];
 72         while(c!='/' && c!='\0' && u.u_error==0) {
 73                 if(cp < &u.u_dbuf[DIRSIZ])
 74                         *cp++ = c;
 75                 c = (*func)();
 76         }
 77         while(cp < &u.u_dbuf[DIRSIZ])
 78                 *cp++ = '\0';
 79         while(c == '/')
 80                 c = (*func)();
 81         if(u.u_error)
 82                 goto out;
 83 
 84         /*
 85          * Set up to search a directory.
 86          */
 87 
 88         u.u_offset[1] = 0;
 89         u.u_offset[0] = 0;
 90         u.u_segflg = 1;
 91         eo = 0;
 92         u.u_count = ldiv(dp->i_size1, DIRSIZ+2);
 93         bp = NULL;
 94 
 95 eloop:
 96 
 97         /*
 98          * If at the end of the directory,
 99          * the search failed. Report what
100          * is appropriate as per flag.
101          */
102 
103         if(u.u_count == 0) {
104                 if(bp != NULL)
105                         brelse(bp);
106                 if(flag==1 && c=='\0') {
107                         if(access(dp, IWRITE))
108                                 goto out;
109                         u.u_pdir = dp;
110                         if(eo)
111                                 u.u_offset[1] = eo-DIRSIZ-2; else
112                                 dp->i_flag =| IUPD;
113                         return(NULL);
114                 }
115                 u.u_error = ENOENT;
116                 goto out;
117         }
118 
119         /*
120          * If offset is on a block boundary,
121          * read the next directory block.
122          * Release previous if it exists.
123          */
124 
125         if((u.u_offset[1]&0777) == 0) {
126                 if(bp != NULL)
127                         brelse(bp);
128                 bp = bread(dp->i_dev,
129                         bmap(dp, ldiv(u.u_offset[1], 512)));
130         }
131 
132         /*
133          * Note first empty directory slot
134          * in eo for possible creat.
135          * String compare the directory entry
136          * and the current component.
137          * If they do not match, go back to eloop.
138          */
139 
140         bcopy(bp->b_addr+(u.u_offset[1]&0777), &u.u_dent, (DIRSIZ+2)/2);
141         u.u_offset[1] =+ DIRSIZ+2;
142         u.u_count--;
143         if(u.u_dent.u_ino == 0) {
144                 if(eo == 0)
145                         eo = u.u_offset[1];
146                 goto eloop;
147         }
148         for(cp = &u.u_dbuf[0]; cp < &u.u_dbuf[DIRSIZ]; cp++)
149                 if(*cp != cp[u.u_dent.u_name - u.u_dbuf])
150                         goto eloop;
151 
152         /*
153          * Here a component matched in a directory.
154          * If there is more pathname, go back to
155          * cloop, otherwise return.
156          */
157 
158         if(bp != NULL)
159                 brelse(bp);
160         if(flag==2 && c=='\0') {
161                 if(access(dp, IWRITE))
162                         goto out;
163                 return(dp);
164         }
165         bp = dp->i_dev;
166         iput(dp);
167         dp = iget(bp, u.u_dent.u_ino);
168         if(dp == NULL)
169                 return(NULL);
170         goto cloop;
171 
172 out:
173         iput(dp);
174         return(NULL);
175 }
176 
177 /*
178  * Return the next character from the
179  * kernel string pointed at by dirp.
180  */
181 schar()
182 {
183 
184         return(*u.u_dirp++ & 0377);
185 }
186 
187 /*
188  * Return the next character from the
189  * user string pointed at by dirp.
190  */
191 uchar()
192 {
193         register c;
194 
195         c = fubyte(u.u_dirp++);
196         if(c == -1)
197                 u.u_error = EFAULT;
198         return(c);
199 }
200 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp