aboutsummaryrefslogtreecommitdiff
path: root/man/man3/9p-file.html
blob: 63ae50427c3060d38871bc0b32896159d05b6e09 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
<head>
<title>9p-file(3) - Plan 9 from User Space</title>
<meta content="text/html; charset=utf-8" http-equiv=Content-Type>
</head>
<body bgcolor=#ffffff>
<table border=0 cellpadding=0 cellspacing=0 width=100%>
<tr height=10><td>
<tr><td width=20><td>
<tr><td width=20><td><b>9P-FILE(3)</b><td align=right><b>9P-FILE(3)</b>
<tr><td width=20><td colspan=2>
    <br>
<p><font size=+1><b>NAME     </b></font><br>

<table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>

    Tree, alloctree, freetree, File, createfile, closefile, removefile,
    walkfile, opendirfile, readdirfile, closedirfile, hasperm &ndash; in-memory
    file hierarchy<br>
    
</table>
<p><font size=+1><b>SYNOPSIS     </b></font><br>

<table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>

    <tt><font size=+1>#include &lt;u.h&gt;<br>
    #include &lt;libc.h&gt;<br>
    #include &lt;fcall.h&gt;<br>
    #include &lt;thread.h&gt;<br>
    #include &lt;9p.h&gt;<br>
    
    <table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
    
    typedef struct File<br>
    {<br>
    
    <table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>

        
        <table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>

            Ref;<br>
            Dir;<br>
            void*aux;<br>
            
        </table>
        
    </table>
    </font></tt>
    <table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>

        
        <table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>

            <i>...<br>
            </i>
        </table>
        
    </table>
    <tt><font size=+1>} File;<br>
    
    <table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
    
    typedef struct Tree<br>
    {<br>
    
    <table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>

        
        <table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>

            File *root;<br>
            
        </table>
        
    </table>
    </font></tt>
    <table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>

        
        <table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>

            <i>...<br>
            </i>
        </table>
        
    </table>
    <tt><font size=+1>} Tree;<br>
    
    <table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
    
    Tree* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alloctree(char *uid, char *gid, ulong mode,<br>
      
    <table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>

        
        <table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>

            void (*destroy)(File*))<br>
            
        </table>
        
    </table>
    void &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;freetree(Tree *tree)<br>
    File* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;createfile(File *dir, char *name, char *uid,<br>
      
    <table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>

        
        <table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>

            ulong mode, void *aux)<br>
            
        </table>
        
    </table>
    int &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;removefile(File *file)<br>
    void &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;closefile(File *file)<br>
    File* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;walkfile(File *dir, char *path)<br>
    Readdir* opendirfile(File *dir)<br>
    long &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;readdirfile(Readdir *rdir, char *buf, long n)<br>
    void &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;closedirfile(Readdir *rdir)<br>
    int &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hasperm(File *file, char *uid, int p)<br>
    </font></tt>
</table>
<p><font size=+1><b>DESCRIPTION     </b></font><br>

<table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>

    <tt><font size=+1>File</font></tt>s and <tt><font size=+1>Tree</font></tt>s provide an in-memory file hierarchy intended for
    use in 9P file servers. 
    <table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
    
    <i>Alloctree</i> creates a new tree of files, and <i>freetree</i> destroys it.
    The root of the tree (also the <tt><font size=+1>root</font></tt> element in the structure)
    will have mode <i>mode</i> and be owned by user <i>uid</i> and group <i>gid</i>. <i>Destroy</i>
    is used when freeing <tt><font size=+1>File</font></tt> structures and is described later. 
    <table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
    
    <tt><font size=+1>File</font></tt>s (including directories) other than the root are created
    using <i>createfile</i>, which attempts to create a file named <i>name</i> in
    the directory <i>dir</i>. If created, the file will have owner <i>uid</i> and
    have a group inherited from the directory. <i>Mode</i> and the permissions
    of <i>dir</i> are used to calculate the permission bits for the file
    as
    described in <i>open</i>(9p). It is permissible for <i>name</i> to be a slash-separated
    path rather than a single element. 
    <table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
    
    <i>Removefile</i> removes a file from the file tree. The file will not
    be freed until the last reference to it has been removed. Directories
    may only be removed when empty. <i>Removefile</i> returns zero on success,
    &ndash;1 on error. It is correct to consider <i>removefile</i> to be <i>closefile</i>
    with the side effect of removing the file when possible. 
    <table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
    
    <i>Walkfile</i> evaluates <i>path</i> relative to the directory <i>dir</i>, returning
    the resulting file, or zero if the named file or any intermediate
    element does not exist. 
    <table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
    
    The <tt><font size=+1>File</font></tt> structure&#8217;s <tt><font size=+1>aux</font></tt> pointer may be used by the client for
    per-<tt><font size=+1>File</font></tt> storage. <tt><font size=+1>File</font></tt>s are reference-counted: if not zero, <i>destroy</i>
    (specified in the call to <i>alloctree</i>) will be called for each file
    when its last reference is removed or when the tree is freed.
    <i>Destroy</i> should take care of any necessary cleanup related to
    <tt><font size=+1>aux</font></tt>. When creating new file references by copying pointers, call
    <i>incref</i> (see <a href="../man3/lock.html"><i>lock</i>(3)</a>) to update the reference count. To note the
    removal of a reference to a file, call <i>closefile</i>. <i>Createfile</i> and
    <i>walkfile</i> return new references. <i>Removefile</i>, <i>closefile</i>, and <i>walkfile</i>
    (but not <i>createfile</i>) consume the passed reference. 
    <table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
    
    Directories may be read, yielding a directory entry structure
    (see <i>stat</i>(9p)) for each file in the directory. In order to allow
    concurrent reading of directories, clients must obtain a <tt><font size=+1>Readdir</font></tt>
    structure by calling <i>opendirfile</i> on a directory. Subsequent calls
    to <i>readdirfile</i> will each yield an integral number of machine-
    independent stat buffers, until end of directory. When finished,
    call <i>closedirfile</i> to free the <tt><font size=+1>Readdir</font></tt>. 
    <table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
    
    <i>Hasperm</i> does simplistic permission checking; it assumes only one-user
    groups named by uid and returns non-zero if <i>uid</i> has permission
    <i>p</i> (a bitwise-or of <tt><font size=+1>AREAD</font></tt>, <tt><font size=+1>AWRITE</font></tt> and <tt><font size=+1>AEXEC</font></tt>) according to <i>file</i><tt><font size=+1>&#8722;&gt;mode</font></tt>.
    9P servers written using <tt><font size=+1>File</font></tt> trees will do standard permission
    checks automatically; <i>hasperm</i> may be
    called explicitly to do additional checks. A 9P server may link
    against a different <i>hasperm</i> implementation to provide more complex
    groups.<br>
    
</table>
<p><font size=+1><b>EXAMPLE     </b></font><br>

<table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>

    The following code correctly handles references when elementwise
    walking a path and creating a file.<br>
    
    <table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>

        <tt><font size=+1>f = tree&#8722;&gt;root;<br>
        incref(f);<br>
        for(i=0; i&lt;n &amp;&amp; f!=nil; i++)<br>
        
        <table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>

            f = walkfile(f, elem[i]);<br>
            
        </table>
        if(f == nil)<br>
        
        <table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>

            return nil;<br>
            
        </table>
        nf = createfile(f, &quot;foo&quot;, &quot;nls&quot;, 0666, nil);<br>
        closefile(f);<br>
        return nf;<br>
        </font></tt>
    </table>
    
</table>
<p><font size=+1><b>SOURCE     </b></font><br>

<table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>

    <tt><font size=+1>/usr/local/plan9/src/lib9p/file.c<br>
    </font></tt>
</table>
<p><font size=+1><b>SEE ALSO    </b></font><br>

<table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>

    <a href="../man3/9p.html"><i>9p</i>(3)</a><br>
    
</table>
<p><font size=+1><b>BUGS     </b></font><br>

<table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>

    The reference counting is cumbersome.<br>
    
</table>

<td width=20>
<tr height=20><td>
</table>
<!-- TRAILER -->
<table border=0 cellpadding=0 cellspacing=0 width=100%>
<tr height=15><td width=10><td><td width=10>
<tr><td><td>
<center>
<a href="../../"><img src="../../dist/spaceglenda100.png" alt="Space Glenda" border=1></a>
</center>
</table>
<!-- TRAILER -->
</body></html>