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.
26 #include <sys/types.h>
28 #include <sys/param.h>
31 static int nixio_open(lua_State *L) {
32 const char *filename = luaL_checklstring(L, 1, NULL);
33 int flags = luaL_optint(L, 2, O_RDONLY);
34 int mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
38 fd = open(filename, flags, mode);
39 } while (fd == -1 && errno == EINTR);
41 return nixio__perror(L);
44 int *udata = lua_newuserdata(L, sizeof(int));
46 return luaL_error(L, "out of memory");
51 luaL_getmetatable(L, NIXIO_FILE_META);
52 lua_setmetatable(L, -2);
57 static int nixio_open_flags(lua_State *L) {
59 const int j = lua_gettop(L);
60 for (int i=1; i<=j; i++) {
61 const char *flag = luaL_checkstring(L, i);
62 if (!strcmp(flag, "append")) {
64 } else if (!strcmp(flag, "creat")) {
66 } else if (!strcmp(flag, "excl")) {
68 } else if (!strcmp(flag, "nonblock") || !strcmp(flag, "ndelay")) {
70 } else if (!strcmp(flag, "sync")) {
72 } else if (!strcmp(flag, "trunc")) {
74 } else if (!strcmp(flag, "rdonly")) {
76 } else if (!strcmp(flag, "wronly")) {
78 } else if (!strcmp(flag, "rdwr")) {
81 return luaL_argerror(L, i, "supported values: append, creat, "
82 "excl, nonblock, ndelay, sync, trunc");
85 lua_pushinteger(L, mode);
89 static int nixio_dup(lua_State *L) {
90 int oldfd = nixio__checkfd(L, 1);
91 int newfd = (lua_gettop(L) > 1) ? nixio__checkfd(L, 2) : -1;
92 int stat = (newfd == -1) ? dup(oldfd) : dup2(oldfd, newfd);
95 return nixio__perror(L);
97 int *udata = lua_newuserdata(L, sizeof(int));
99 return luaL_error(L, "out of memory");
103 luaL_getmetatable(L, NIXIO_FILE_META);
104 lua_setmetatable(L, -2);
109 static int nixio_pipe(lua_State *L) {
110 int pipefd[2], *udata;
112 return nixio__perror(L);
115 luaL_getmetatable(L, NIXIO_FILE_META);
116 udata = lua_newuserdata(L, sizeof(int));
118 return luaL_error(L, "out of memory");
122 lua_pushvalue(L, -2);
123 lua_setmetatable(L, -2);
126 udata = lua_newuserdata(L, sizeof(int));
128 return luaL_error(L, "out of memory");
132 lua_pushvalue(L, -3);
133 lua_setmetatable(L, -2);
138 static int nixio_file_write(lua_State *L) {
139 int fd = nixio__checkfd(L, 1);
142 const char *data = luaL_checklstring(L, 2, &len);
145 sent = write(fd, data, len);
146 } while(sent == -1 && errno == EINTR);
148 lua_pushinteger(L, sent);
151 return nixio__perror(L);
155 static int nixio_file_read(lua_State *L) {
156 int fd = nixio__checkfd(L, 1);
157 char buffer[NIXIO_BUFFERSIZE];
158 int req = luaL_checkinteger(L, 2);
161 /* We limit the readsize to NIXIO_BUFFERSIZE */
162 req = (req > NIXIO_BUFFERSIZE) ? NIXIO_BUFFERSIZE : req;
165 readc = read(fd, buffer, req);
166 } while (readc == -1 && errno == EINTR);
169 return nixio__perror(L);
171 lua_pushlstring(L, buffer, readc);
177 static int nixio_file_seek(lua_State *L) {
178 int fd = nixio__checkfd(L, 1);
179 off_t len = (off_t)luaL_checknumber(L, 2);
181 const char *whstr = luaL_optlstring(L, 3, "set", NULL);
182 if (!strcmp(whstr, "set")) {
184 } else if (!strcmp(whstr, "cur")) {
186 } else if (!strcmp(whstr, "end")) {
189 return luaL_argerror(L, 3, "supported values: set, cur, end");
191 len = lseek(fd, len, whence);
193 return nixio__perror(L);
195 lua_pushnumber(L, len);
200 static int nixio_file_tell(lua_State *L) {
201 int fd = nixio__checkfd(L, 1);
202 off_t pos = lseek(fd, 0, SEEK_CUR);
204 return nixio__perror(L);
206 lua_pushnumber(L, pos);
211 static int nixio_file_sync(lua_State *L) {
212 int fd = nixio__checkfd(L, 1);
214 int meta = lua_toboolean(L, 2);
215 return nixio__pstatus(L, (meta) ? !fsync(fd) : !fdatasync(fd));
217 return nixio__pstatus(L, !fsync(fd));
221 static int nixio_file_lock(lua_State *L) {
222 int fd = nixio__checkfd(L, 1);
223 const char *flag = luaL_checkstring(L, 2);
224 off_t len = (off_t)luaL_optnumber(L, 3, 0);
228 if (!strcmp(flag, "lock")) {
230 } else if (!strcmp(flag, "tlock")) {
232 } else if (!strcmp(flag, "ulock")) {
234 } else if (!strcmp(flag, "test")) {
237 return luaL_argerror(L, 2,
238 "supported values: lock, tlock, ulock, test");
242 stat = lockf(fd, cmd, len);
243 } while (stat == -1 && errno == EINTR);
245 return nixio__pstatus(L, !stat);
248 static int nixio_file_close(lua_State *L) {
249 int *fdp = luaL_checkudata(L, 1, NIXIO_FILE_META);
250 luaL_argcheck(L, *fdp != -1, 1, "invalid file object");
254 } while (res == -1 && errno == EINTR);
256 return nixio__pstatus(L, !res);
259 static int nixio_file__gc(lua_State *L) {
260 int *fdp = luaL_checkudata(L, 1, NIXIO_FILE_META);
265 } while (res == -1 && errno == EINTR);
272 * string representation
274 static int nixio_file__tostring(lua_State *L) {
275 lua_pushfstring(L, "nixio file %d", nixio__tofd(L, 1));
280 static const luaL_reg M[] = {
281 {"write", nixio_file_write},
282 {"read", nixio_file_read},
283 {"tell", nixio_file_tell},
284 {"seek", nixio_file_seek},
285 {"sync", nixio_file_sync},
286 {"lock", nixio_file_lock},
287 {"close", nixio_file_close},
288 {"__gc", nixio_file__gc},
289 {"__tostring", nixio_file__tostring},
294 static const luaL_reg R[] = {
296 {"open", nixio_open},
297 {"open_flags", nixio_open_flags},
298 {"pipe", nixio_pipe},
302 void nixio_open_file(lua_State *L) {
303 luaL_register(L, NULL, R);
305 luaL_newmetatable(L, NIXIO_FILE_META);
306 luaL_register(L, NULL, M);
307 lua_pushvalue(L, -1);
308 lua_setfield(L, -2, "__index");
309 lua_setfield(L, -2, "meta_file");