13 #include "lixp_debug.h"
14 #include "lixp_util.h"
15 #include "lixp_instance.h"
18 /* ------------------------------------------------------------------------
22 struct ixp
*lixp_checkixp (lua_State
*L
, int narg
)
24 void *ud
= luaL_checkudata (L
, narg
, L_IXP_MT
);
25 luaL_argcheck (L
, ud
!= NULL
, 1, "`ixp' expected");
26 return (struct ixp
*)ud
;
29 int l_ixp_tostring (lua_State
*L
)
31 struct ixp
*ixp
= lixp_checkixp (L
, 1);
32 lua_pushfstring (L
, "ixp instance %p", ixp
);
36 /* ------------------------------------------------------------------------
37 * lua: write(file, data) -- writes data to a file
40 int l_ixp_write (lua_State
*L
)
49 ixp
= lixp_checkixp (L
, 1);
50 file
= luaL_checkstring (L
, 2);
51 data
= luaL_checklstring (L
, 3, &data_len
);
53 fid
= ixp_open(ixp
->client
, file
, P9_OWRITE
);
55 return lixp_pusherror (L
, "count not open p9 file");
57 DBGF("** ixp.write (%s,%s) **\n", file
, data
);
59 rc
= lixp_write_data (fid
, data
, data_len
);
62 return lixp_pusherror (L
, "failed to write to p9 file");
69 /* ------------------------------------------------------------------------
70 * lua: data [,short_read] = read(file, [max_buffer_size])
71 * -- returns contents of file
73 * max_buffer_size limits the read to IXP_READ_MAX_BUFFER_SIZE by default, but
74 * can be configured to a different value. Setting max_buffer_size to zero
75 * means no limit will be applied.
77 * On return data holds the data read, and short_read indicates if there was
78 * more data that was not read.
80 * If the file contents are expected to be large use l_ixp_iread(), which
81 * iterates over the file.
83 int l_ixp_read (lua_State
*L
)
89 size_t buf_ofs
, buf_size
;
90 lua_Number max_buffer_size
;
94 ixp
= lixp_checkixp (L
, 1);
95 file
= luaL_checkstring (L
, 2);
96 max_buffer_size
= luaL_optnumber (L
, 3, IXP_READ_MAX_BUFFER_SIZE
);
98 fid
= ixp_open(ixp
->client
, file
, P9_OREAD
);
100 return lixp_pusherror (L
, "count not open p9 file");
102 buf_size
= fid
->iounit
;
103 if (max_buffer_size
&& buf_size
> max_buffer_size
)
104 buf_size
= max_buffer_size
;
105 buf
= malloc (buf_size
);
108 return lixp_pusherror (L
, "count not allocate memory");
112 DBGF("** ixp.read (%s) **\n", file
);
115 int rc
= ixp_read (fid
, buf
+buf_ofs
, buf_size
-buf_ofs
);
122 return lixp_pusherror (L
, "failed to read from p9 file");
127 if (buf_ofs
> buf_size
)
128 return lixp_pusherror (L
, "internal error while reading");
130 if (buf_ofs
== buf_size
)
133 if (max_buffer_size
&& buf_size
>= max_buffer_size
)
136 realloc_size
= max_buffer_size
;
137 if (!max_buffer_size
)
138 realloc_size
= buf_size
* 2;
141 if (realloc_size
> buf_size
)
142 _buf
= realloc (buf
, realloc_size
);
147 return lixp_pusherrorf(L
, "failed to allocate %u bytes",
151 buf_size
= realloc_size
;
156 if (memchr(buf
, '\0', buf_ofs
))
157 fprintf(stderr
, "** WARNING: ixp.read (%s): result contains null characters **\n", file
);
159 lua_pushlstring(L
, buf
, buf_ofs
);
160 lua_pushboolean(L
, short_read
);
164 /* ------------------------------------------------------------------------
165 * lua: create(file, [data]) -- create a file, optionally write data to it
167 int l_ixp_create (lua_State
*L
)
175 ixp
= lixp_checkixp (L
, 1);
176 file
= luaL_checkstring (L
, 2);
177 data
= luaL_optlstring (L
, 3, NULL
, &data_len
);
179 DBGF("** ixp.create (%s) **\n", file
);
181 fid
= ixp_create (ixp
->client
, file
, 0777, P9_OWRITE
);
183 return lixp_pusherror (L
, "count not create file");
186 && !(fid
->qid
.type
& P9_DMDIR
)) {
187 int rc
= lixp_write_data (fid
, data
, data_len
);
190 return lixp_pusherror (L
, "failed to write to p9 file");
198 /* ------------------------------------------------------------------------
199 * lua: remove(file) -- remove a file
201 int l_ixp_remove (lua_State
*L
)
207 ixp
= lixp_checkixp (L
, 1);
208 file
= luaL_checkstring (L
, 2);
210 DBGF("** ixp.remove (%s) **\n", file
);
212 rc
= ixp_remove (ixp
->client
, file
);
214 return lixp_pusherror (L
, "failed to remove p9 file");
219 /* ------------------------------------------------------------------------
220 * lua: itr = iread(file) -- returns a line iterator
223 struct l_ixp_iread_s
{
231 static int iread_iter (lua_State
*L
);
233 int l_ixp_iread (lua_State
*L
)
237 struct l_ixp_iread_s
*ctx
;
239 ixp
= lixp_checkixp (L
, 1);
240 file
= luaL_checkstring (L
, 2);
242 ctx
= (struct l_ixp_iread_s
*)lua_newuserdata (L
, sizeof(*ctx
));
244 return lixp_pusherror (L
, "count not allocate context");
245 memset (ctx
, 0, sizeof (*ctx
));
247 // set the metatable for the new userdata
248 luaL_getmetatable (L
, L_IXP_IREAD_MT
);
249 lua_setmetatable (L
, -2);
251 ctx
->fid
= ixp_open(ixp
->client
, file
, P9_OREAD
);
252 if(ctx
->fid
== NULL
) {
253 return lixp_pusherror (L
, "count not open p9 file");
256 DBGF("** ixp.iread (%s) **\n", file
);
258 // create and return the iterator function
259 // the only argument is the userdata
260 lua_pushcclosure (L
, iread_iter
, 1);
264 static int iread_iter (lua_State
*L
)
266 struct l_ixp_iread_s
*ctx
;
269 ctx
= (struct l_ixp_iread_s
*)lua_touserdata (L
, lua_upvalueindex(1));
271 DBGF("** ixp.iread - iter **\n");
274 ctx
->buf
= malloc (ctx
->fid
->iounit
);
276 return lixp_pusherror (L
, "count not allocate memory");
277 ctx
->buf_size
= ctx
->fid
->iounit
;
284 rc
= ixp_read (ctx
->fid
, ctx
->buf
, ctx
->buf_size
);
286 return 0; // we are done
291 s
= ctx
->buf
+ ctx
->buf_pos
;
293 cr
= strchr (s
, '\n');
295 // no match, just return the whole thing
296 // TODO: should read more upto a cr or some limit
297 if (memchr(s
, '\0', ctx
->buf_len
))
298 fprintf(stderr
, "** WARNING: ixp.iread - iter: result contains null characters **\n");
299 lua_pushlstring (L
, s
, ctx
->buf_len
);
304 // we have a match s..cr is our sub string
306 if (memchr(s
, '\0', len
))
307 fprintf(stderr
, "** WARNING: ixp.iread - iter: result contains null characters **\n");
308 lua_pushlstring (L
, s
, len
);
316 static int iread_gc (lua_State
*L
)
318 struct l_ixp_iread_s
*ctx
;
320 ctx
= (struct l_ixp_iread_s
*)lua_touserdata (L
, 1);
322 DBGF("** ixp.iread - gc **\n");
324 ixp_close (ctx
->fid
);
332 void lixp_init_iread_mt (lua_State
*L
)
334 luaL_newmetatable(L
, L_IXP_IREAD_MT
);
336 // setup the __gc field
337 lua_pushstring (L
, "__gc");
338 lua_pushcfunction (L
, iread_gc
);
339 lua_settable (L
, -3);
342 /* ------------------------------------------------------------------------
343 * lua: stat = stat(file) -- returns a status table
346 int l_ixp_stat (lua_State
*L
)
349 struct IxpStat
*stat
;
353 ixp
= lixp_checkixp (L
, 1);
354 file
= luaL_checkstring (L
, 2);
356 DBGF("** ixp.stat (%s) **\n", file
);
358 stat
= ixp_stat(ixp
->client
, file
);
360 return lixp_pusherror(L
, "cannot stat file");
362 rc
= lixp_pushstat (L
, stat
);
369 /* ------------------------------------------------------------------------
370 * lua: itr = idir(dir) -- returns a file name iterator
373 struct l_ixp_idir_s
{
379 static int idir_iter (lua_State
*L
);
381 int l_ixp_idir (lua_State
*L
)
385 struct l_ixp_idir_s
*ctx
;
387 ixp
= lixp_checkixp (L
, 1);
388 file
= luaL_checkstring (L
, 2);
390 ctx
= (struct l_ixp_idir_s
*)lua_newuserdata (L
, sizeof(*ctx
));
392 return lixp_pusherror (L
, "count not allocate context");
393 memset(ctx
, 0, sizeof (*ctx
));
395 // set the metatable for the new userdata
396 luaL_getmetatable (L
, L_IXP_IDIR_MT
);
397 lua_setmetatable (L
, -2);
399 ctx
->fid
= ixp_open(ixp
->client
, file
, P9_OREAD
);
400 if(ctx
->fid
== NULL
) {
401 return lixp_pusherror (L
, "count not open p9 file");
404 ctx
->buf
= malloc (ctx
->fid
->iounit
);
406 ixp_close (ctx
->fid
);
408 return lixp_pusherror (L
, "count not allocate memory");
411 DBGF("** ixp.idir (%s) **\n", file
);
413 // create and return the iterator function
414 // the only argument is the userdata
415 lua_pushcclosure (L
, idir_iter
, 1);
419 static int idir_iter (lua_State
*L
)
421 struct l_ixp_idir_s
*ctx
;
424 ctx
= (struct l_ixp_idir_s
*)lua_touserdata (L
, lua_upvalueindex(1));
426 DBGF("** ixp.idir - iter **\n");
428 if (ctx
->m
.pos
>= ctx
->m
.end
) {
429 int rc
= ixp_read (ctx
->fid
, ctx
->buf
, ctx
->fid
->iounit
);
434 ctx
->m
= ixp_message(ctx
->buf
, rc
, MsgUnpack
);
435 if (ctx
->m
.pos
>= ctx
->m
.end
)
439 ixp_pstat(&ctx
->m
, &stat
);
441 return lixp_pushstat (L
, &stat
);
444 static int idir_gc (lua_State
*L
)
446 struct l_ixp_idir_s
*ctx
;
448 ctx
= (struct l_ixp_idir_s
*)lua_touserdata (L
, 1);
450 DBGF("** ixp.idir - gc **\n");
454 ixp_close (ctx
->fid
);
459 void lixp_init_idir_mt (lua_State
*L
)
461 luaL_newmetatable(L
, L_IXP_IDIR_MT
);
463 // setup the __gc field
464 lua_pushstring (L
, "__gc");
465 lua_pushcfunction (L
, idir_gc
);
466 lua_settable (L
, -3);