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 static int nil_iter (lua_State
*L
)
41 /* ------------------------------------------------------------------------
42 * lua: write(file, data) -- writes data to a file
45 int l_ixp_write (lua_State
*L
)
54 ixp
= lixp_checkixp (L
, 1);
55 file
= luaL_checkstring (L
, 2);
56 data
= luaL_checklstring (L
, 3, &data_len
);
58 fid
= ixp_open(ixp
->client
, file
, P9_OWRITE
);
60 return lixp_pusherror (L
, "count not open p9 file");
62 DBGF("** ixp.write (%s,%s) **\n", file
, data
);
64 rc
= lixp_write_data (fid
, data
, data_len
);
67 return lixp_pusherror (L
, "failed to write to p9 file");
74 /* ------------------------------------------------------------------------
75 * lua: data [,short_read] = read(file, [max_buffer_size])
76 * -- returns contents of file
78 * max_buffer_size limits the read to IXP_READ_MAX_BUFFER_SIZE by default, but
79 * can be configured to a different value. Setting max_buffer_size to zero
80 * means no limit will be applied.
82 * On return data holds the data read, and short_read indicates if there was
83 * more data that was not read.
85 * If the file contents are expected to be large use l_ixp_iread(), which
86 * iterates over the file.
88 int l_ixp_read (lua_State
*L
)
94 size_t buf_ofs
, buf_size
;
95 lua_Number max_buffer_size
;
99 ixp
= lixp_checkixp (L
, 1);
100 file
= luaL_checkstring (L
, 2);
101 max_buffer_size
= luaL_optnumber (L
, 3, IXP_READ_MAX_BUFFER_SIZE
);
103 fid
= ixp_open(ixp
->client
, file
, P9_OREAD
);
105 return lixp_pusherror (L
, "count not open p9 file");
107 buf_size
= fid
->iounit
;
108 if (max_buffer_size
&& buf_size
> max_buffer_size
)
109 buf_size
= max_buffer_size
;
110 buf
= malloc (buf_size
);
113 return lixp_pusherror (L
, "count not allocate memory");
117 DBGF("** ixp.read (%s) **\n", file
);
120 int rc
= ixp_read (fid
, buf
+buf_ofs
, buf_size
-buf_ofs
);
127 return lixp_pusherror (L
, "failed to read from p9 file");
132 if (buf_ofs
> buf_size
)
133 return lixp_pusherror (L
, "internal error while reading");
135 if (buf_ofs
== buf_size
)
138 if (max_buffer_size
&& buf_size
>= max_buffer_size
)
141 realloc_size
= max_buffer_size
;
142 if (!max_buffer_size
)
143 realloc_size
= buf_size
* 2;
146 if (realloc_size
> buf_size
)
147 _buf
= realloc (buf
, realloc_size
);
152 return lixp_pusherrorf(L
, "failed to allocate %u bytes",
156 buf_size
= realloc_size
;
161 if (memchr(buf
, '\0', buf_ofs
))
162 fprintf(stderr
, "** WARNING: ixp.read (%s): result contains null characters **\n", file
);
164 lua_pushlstring(L
, buf
, buf_ofs
);
165 lua_pushboolean(L
, short_read
);
169 /* ------------------------------------------------------------------------
170 * lua: create(file, [data]) -- create a file, optionally write data to it
172 int l_ixp_create (lua_State
*L
)
180 ixp
= lixp_checkixp (L
, 1);
181 file
= luaL_checkstring (L
, 2);
182 data
= luaL_optlstring (L
, 3, NULL
, &data_len
);
184 DBGF("** ixp.create (%s) **\n", file
);
186 fid
= ixp_create (ixp
->client
, file
, 0777, P9_OWRITE
);
188 return lixp_pusherror (L
, "count not create file");
191 && !(fid
->qid
.type
& P9_DMDIR
)) {
192 int rc
= lixp_write_data (fid
, data
, data_len
);
195 return lixp_pusherror (L
, "failed to write to p9 file");
203 /* ------------------------------------------------------------------------
204 * lua: remove(file) -- remove a file
206 int l_ixp_remove (lua_State
*L
)
212 ixp
= lixp_checkixp (L
, 1);
213 file
= luaL_checkstring (L
, 2);
215 DBGF("** ixp.remove (%s) **\n", file
);
217 rc
= ixp_remove (ixp
->client
, file
);
219 return lixp_pusherror (L
, "failed to remove p9 file");
224 /* ------------------------------------------------------------------------
225 * lua: itr = iread(file) -- returns a line iterator
228 struct l_ixp_iread_s
{
236 static int iread_iter (lua_State
*L
);
238 int l_ixp_iread (lua_State
*L
)
242 struct l_ixp_iread_s
*ctx
;
244 ixp
= lixp_checkixp (L
, 1);
245 file
= luaL_checkstring (L
, 2);
247 ctx
= (struct l_ixp_iread_s
*)lua_newuserdata (L
, sizeof(*ctx
));
249 DBGF("** ixp.iread (%s) - count not allocate context", file
);
250 lua_pushcclosure (L
, nil_iter
, 1);
253 memset (ctx
, 0, sizeof (*ctx
));
255 ctx
->fid
= ixp_open(ixp
->client
, file
, P9_OREAD
);
256 if(ctx
->fid
== NULL
) {
257 DBGF("** ixp.iread (%s) - count not open p9 file", file
);
258 lua_pushcclosure (L
, nil_iter
, 1);
262 // set the metatable for the new userdata
263 luaL_getmetatable (L
, L_IXP_IREAD_MT
);
264 lua_setmetatable (L
, -2);
266 DBGF("** ixp.iread (%s) - iterator ready **\n", file
);
268 // create and return the iterator function
269 // the only argument is the userdata
270 lua_pushcclosure (L
, iread_iter
, 1);
274 static int iread_iter (lua_State
*L
)
276 struct l_ixp_iread_s
*ctx
;
279 ctx
= (struct l_ixp_iread_s
*)lua_touserdata (L
, lua_upvalueindex(1));
281 DBGF("** ixp.iread - iter **\n");
284 ctx
->buf
= malloc (ctx
->fid
->iounit
);
286 return lixp_pusherror (L
, "count not allocate memory");
287 ctx
->buf_size
= ctx
->fid
->iounit
;
294 rc
= ixp_read (ctx
->fid
, ctx
->buf
, ctx
->buf_size
);
296 return 0; // we are done
301 s
= ctx
->buf
+ ctx
->buf_pos
;
303 cr
= strchr (s
, '\n');
305 // no match, just return the whole thing
306 // TODO: should read more upto a cr or some limit
307 if (memchr(s
, '\0', ctx
->buf_len
))
308 fprintf(stderr
, "** WARNING: ixp.iread - iter: result contains null characters **\n");
309 lua_pushlstring (L
, s
, ctx
->buf_len
);
314 // we have a match s..cr is our sub string
316 if (memchr(s
, '\0', len
))
317 fprintf(stderr
, "** WARNING: ixp.iread - iter: result contains null characters **\n");
318 lua_pushlstring (L
, s
, len
);
326 static int iread_gc (lua_State
*L
)
328 struct l_ixp_iread_s
*ctx
;
330 ctx
= (struct l_ixp_iread_s
*)lua_touserdata (L
, 1);
332 DBGF("** ixp.iread - gc **\n");
334 ixp_close (ctx
->fid
);
342 void lixp_init_iread_mt (lua_State
*L
)
344 luaL_newmetatable(L
, L_IXP_IREAD_MT
);
346 // setup the __gc field
347 lua_pushstring (L
, "__gc");
348 lua_pushcfunction (L
, iread_gc
);
349 lua_settable (L
, -3);
352 /* ------------------------------------------------------------------------
353 * lua: stat = stat(file) -- returns a status table
356 int l_ixp_stat (lua_State
*L
)
359 struct IxpStat
*stat
;
363 ixp
= lixp_checkixp (L
, 1);
364 file
= luaL_checkstring (L
, 2);
366 DBGF("** ixp.stat (%s) **\n", file
);
368 stat
= ixp_stat(ixp
->client
, file
);
370 return lixp_pusherror(L
, "cannot stat file");
372 rc
= lixp_pushstat (L
, stat
);
379 /* ------------------------------------------------------------------------
380 * lua: itr = idir(dir) -- returns a file name iterator
383 struct l_ixp_idir_s
{
389 static int idir_iter (lua_State
*L
);
391 int l_ixp_idir (lua_State
*L
)
395 struct l_ixp_idir_s
*ctx
;
397 ixp
= lixp_checkixp (L
, 1);
398 file
= luaL_checkstring (L
, 2);
400 DBGF("** ixp.idir (%s) **\n", file
);
402 ctx
= (struct l_ixp_idir_s
*)lua_newuserdata (L
, sizeof(*ctx
));
404 DBGF("** ixp.idir (%s) - count not allocate context", file
);
405 lua_pushcclosure (L
, nil_iter
, 1);
408 memset(ctx
, 0, sizeof (*ctx
));
410 ctx
->fid
= ixp_open(ixp
->client
, file
, P9_OREAD
);
411 if(ctx
->fid
== NULL
) {
412 DBGF("** ixp.idir (%s) - count not open p9 file", file
);
413 lua_pushcclosure (L
, nil_iter
, 1);
417 ctx
->buf
= malloc (ctx
->fid
->iounit
);
419 ixp_close (ctx
->fid
);
421 DBGF("** ixp.idir (%s) - count not allocate memory", file
);
422 lua_pushcclosure (L
, nil_iter
, 1);
426 // set the metatable for the new userdata
427 luaL_getmetatable (L
, L_IXP_IDIR_MT
);
428 lua_setmetatable (L
, -2);
430 DBGF("** ixp.idir (%s) - iterator ready **\n", file
);
432 // create and return the iterator function
433 // the only argument is the userdata
434 lua_pushcclosure (L
, idir_iter
, 1);
438 static int idir_iter (lua_State
*L
)
440 struct l_ixp_idir_s
*ctx
;
443 ctx
= (struct l_ixp_idir_s
*)lua_touserdata (L
, lua_upvalueindex(1));
445 DBGF("** ixp.idir - iter **\n");
447 if (ctx
->m
.pos
>= ctx
->m
.end
) {
448 int rc
= ixp_read (ctx
->fid
, ctx
->buf
, ctx
->fid
->iounit
);
453 ctx
->m
= ixp_message(ctx
->buf
, rc
, MsgUnpack
);
454 if (ctx
->m
.pos
>= ctx
->m
.end
)
458 ixp_pstat(&ctx
->m
, &stat
);
460 return lixp_pushstat (L
, &stat
);
463 static int idir_gc (lua_State
*L
)
465 struct l_ixp_idir_s
*ctx
;
467 ctx
= (struct l_ixp_idir_s
*)lua_touserdata (L
, 1);
469 DBGF("** ixp.idir - gc **\n");
473 ixp_close (ctx
->fid
);
478 void lixp_init_idir_mt (lua_State
*L
)
480 luaL_newmetatable(L
, L_IXP_IDIR_MT
);
482 // setup the __gc field
483 lua_pushstring (L
, "__gc");
484 lua_pushcfunction (L
, idir_gc
);
485 lua_settable (L
, -3);