2 * nixio - Linux I/O library for lua
4 * Copyright (C) 2009 Steven Barth <steven@midlink.org>
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
27 static int nixio_file(lua_State
*L
) {
28 const char *filename
= luaL_checklstring(L
, 1, NULL
);
29 const char *mode
= luaL_optlstring(L
, 2, "r", NULL
);
31 FILE *file
= fopen(filename
, mode
);
33 return nixio__perror(L
);
36 FILE **udata
= lua_newuserdata(L
, sizeof(FILE*));
38 return luaL_error(L
, "out of memory");
43 luaL_getmetatable(L
, NIXIO_FILE_META
);
44 lua_setmetatable(L
, -2);
49 static int nixio_pipe(lua_State
*L
) {
53 return nixio__perror(L
);
56 luaL_getmetatable(L
, NIXIO_FILE_META
);
57 udata
= lua_newuserdata(L
, sizeof(FILE*));
59 return luaL_error(L
, "out of memory");
62 if (!(*udata
= fdopen(pipefd
[0], "r"))) {
63 return nixio__perror(L
);
66 lua_setmetatable(L
, -2);
69 udata
= lua_newuserdata(L
, sizeof(FILE**));
70 if (!(*udata
= fdopen(pipefd
[1], "w"))) {
71 return nixio__perror(L
);
74 lua_setmetatable(L
, -2);
79 static int nixio_file_write(lua_State
*L
) {
80 FILE *fp
= nixio__checkfile(L
);
82 const char *data
= luaL_checklstring(L
, 2, &len
);
83 written
= fwrite(data
, sizeof(char), len
, fp
);
85 return nixio__perror(L
);
87 lua_pushnumber(L
, written
);
93 /* Some code borrowed from Lua 5.1.4 liolib.c */
94 static int nixio_file_read(lua_State
*L
) {
95 FILE *f
= nixio__checkfile(L
);
96 size_t n
= (size_t)luaL_checkinteger(L
, 2);
97 luaL_argcheck(L
, 2, n
>= 0, "invalid length");
103 lua_pushliteral(L
, "");
108 size_t rlen
; /* how much to read */
109 size_t nr
; /* number of chars actually read */
111 luaL_buffinit(L
, &b
);
112 rlen
= LUAL_BUFFERSIZE
; /* try to read that much each time */
115 char *p
= luaL_prepbuffer(&b
);
116 if (rlen
> n
) rlen
= n
; /* cannot read more than asked */
117 nr
= fread(p
, sizeof(char), rlen
, f
);
118 luaL_addsize(&b
, nr
);
119 n
-= nr
; /* still have to read `n' chars */
120 } while (n
> 0 && nr
== rlen
); /* until end of count or eof */
121 luaL_pushresult(&b
); /* close buffer */
122 return (n
== 0 || lua_objlen(L
, -1) > 0);
125 static int nixio_file_seek(lua_State
*L
) {
126 FILE *f
= nixio__checkfile(L
);
127 off_t len
= (off_t
)luaL_checknumber(L
, 2);
129 const char *whstr
= luaL_optlstring(L
, 3, "set", NULL
);
130 if (!strcmp(whstr
, "set")) {
132 } else if (!strcmp(whstr
, "cur")) {
134 } else if (!strcmp(whstr
, "end")) {
137 return luaL_argerror(L
, 3, "supported values: set, cur, end");
139 return nixio__pstatus(L
, !fseeko(f
, len
, whence
));
142 static int nixio_file_tell(lua_State
*L
) {
143 FILE *f
= nixio__checkfile(L
);
144 off_t pos
= ftello(f
);
146 return nixio__perror(L
);
148 lua_pushnumber(L
, (lua_Number
)pos
);
153 static int nixio_file_flush(lua_State
*L
) {
154 FILE *f
= nixio__checkfile(L
);
155 return nixio__pstatus(L
, !fflush(f
));
158 static int nixio_file_close(lua_State
*L
) {
159 FILE **fpp
= (FILE**)luaL_checkudata(L
, 1, NIXIO_FILE_META
);
160 luaL_argcheck(L
, *fpp
, 1, "invalid file object");
161 int res
= fclose(*fpp
);
163 return nixio__pstatus(L
, !res
);
166 static int nixio_file__gc(lua_State
*L
) {
167 FILE **fpp
= (FILE**)luaL_checkudata(L
, 1, NIXIO_FILE_META
);
176 * string representation
178 static int nixio_file__tostring(lua_State
*L
) {
179 lua_pushfstring(L
, "nixio file %d", nixio__tofd(L
, 1));
184 static const luaL_reg M
[] = {
185 {"write", nixio_file_write
},
186 {"read", nixio_file_read
},
187 {"tell", nixio_file_tell
},
188 {"seek", nixio_file_seek
},
189 {"flush", nixio_file_flush
},
190 {"close", nixio_file_close
},
191 {"__gc", nixio_file__gc
},
192 {"__tostring", nixio_file__tostring
},
197 static const luaL_reg R
[] = {
198 {"open", nixio_file
},
199 {"pipe", nixio_pipe
},
203 void nixio_open_file(lua_State
*L
) {
204 luaL_register(L
, NULL
, R
);
206 luaL_newmetatable(L
, NIXIO_FILE_META
);
207 luaL_register(L
, NULL
, M
);
208 lua_pushvalue(L
, -1);
209 lua_setfield(L
, -2, "__index");