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>
30 static int nixio_open(lua_State *L) {
31 const char *filename = luaL_checklstring(L, 1, NULL);
32 int flags = luaL_optint(L, 2, O_RDONLY);
33 int mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
37 fd = open(filename, flags, mode);
38 } while (fd == -1 && errno == EINTR);
40 return nixio__perror(L);
43 int *udata = lua_newuserdata(L, sizeof(int));
45 return luaL_error(L, "out of memory");
50 luaL_getmetatable(L, NIXIO_FILE_META);
51 lua_setmetatable(L, -2);
56 static int nixio_open_flags(lua_State *L) {
58 const int j = lua_gettop(L);
59 for (int i=1; i<=j; i++) {
60 const char *flag = luaL_checkstring(L, i);
61 if (!strcmp(flag, "append")) {
63 } else if (!strcmp(flag, "creat")) {
65 } else if (!strcmp(flag, "excl")) {
67 } else if (!strcmp(flag, "nonblock") || !strcmp(flag, "ndelay")) {
69 } else if (!strcmp(flag, "sync")) {
71 } else if (!strcmp(flag, "trunc")) {
73 } else if (!strcmp(flag, "rdonly")) {
75 } else if (!strcmp(flag, "wronly")) {
77 } else if (!strcmp(flag, "rdwr")) {
80 return luaL_argerror(L, i, "supported values: append, creat, "
81 "excl, nonblock, ndelay, sync, trunc");
84 lua_pushinteger(L, mode);
88 static int nixio_dup(lua_State *L) {
89 int oldfd = nixio__checkfd(L, 1);
90 int newfd = (lua_gettop(L) > 1) ? nixio__checkfd(L, 2) : -1;
91 int stat = (newfd == -1) ? dup(oldfd) : dup2(oldfd, newfd);
94 return nixio__perror(L);
96 int *udata = lua_newuserdata(L, sizeof(int));
98 return luaL_error(L, "out of memory");
102 luaL_getmetatable(L, NIXIO_FILE_META);
103 lua_setmetatable(L, -2);
108 static int nixio_pipe(lua_State *L) {
109 int pipefd[2], *udata;
111 return nixio__perror(L);
114 luaL_getmetatable(L, NIXIO_FILE_META);
115 udata = lua_newuserdata(L, sizeof(int));
117 return luaL_error(L, "out of memory");
121 lua_pushvalue(L, -2);
122 lua_setmetatable(L, -2);
125 udata = lua_newuserdata(L, sizeof(int));
127 return luaL_error(L, "out of memory");
131 lua_pushvalue(L, -3);
132 lua_setmetatable(L, -2);
137 static int nixio_file_write(lua_State *L) {
138 int fd = nixio__checkfd(L, 1);
141 const char *data = luaL_checklstring(L, 2, &len);
144 sent = write(fd, data, len);
145 } while(sent == -1 && errno == EINTR);
147 lua_pushinteger(L, sent);
150 return nixio__perror(L);
154 static int nixio_file_read(lua_State *L) {
155 int fd = nixio__checkfd(L, 1);
156 char buffer[NIXIO_BUFFERSIZE];
157 int req = luaL_checkinteger(L, 2);
160 /* We limit the readsize to NIXIO_BUFFERSIZE */
161 req = (req > NIXIO_BUFFERSIZE) ? NIXIO_BUFFERSIZE : req;
164 readc = read(fd, buffer, req);
165 } while (readc == -1 && errno == EINTR);
168 return nixio__perror(L);
170 lua_pushlstring(L, buffer, readc);
176 static int nixio_file_seek(lua_State *L) {
177 int fd = nixio__checkfd(L, 1);
178 off_t len = (off_t)luaL_checknumber(L, 2);
180 const char *whstr = luaL_optlstring(L, 3, "set", NULL);
181 if (!strcmp(whstr, "set")) {
183 } else if (!strcmp(whstr, "cur")) {
185 } else if (!strcmp(whstr, "end")) {
188 return luaL_argerror(L, 3, "supported values: set, cur, end");
190 len = lseek(fd, len, whence);
192 return nixio__perror(L);
194 lua_pushnumber(L, len);
199 static int nixio_file_tell(lua_State *L) {
200 int fd = nixio__checkfd(L, 1);
201 off_t pos = lseek(fd, 0, SEEK_CUR);
203 return nixio__perror(L);
205 lua_pushnumber(L, pos);
210 static int nixio_file_sync(lua_State *L) {
211 int fd = nixio__checkfd(L, 1);
212 int meta = lua_toboolean(L, 2);
213 return nixio__pstatus(L, (meta) ? !fsync(fd) : !fdatasync(fd));
216 static int nixio_file_lock(lua_State *L) {
217 int fd = nixio__checkfd(L, 1);
218 const char *flag = luaL_checkstring(L, 2);
219 off_t len = (off_t)luaL_optnumber(L, 3, 0);
223 if (!strcmp(flag, "lock")) {
225 } else if (!strcmp(flag, "tlock")) {
227 } else if (!strcmp(flag, "ulock")) {
229 } else if (!strcmp(flag, "test")) {
232 return luaL_argerror(L, 2,
233 "supported values: lock, tlock, ulock, test");
237 stat = lockf(fd, cmd, len);
238 } while (stat == -1 && errno == EINTR);
240 return nixio__pstatus(L, !stat);
243 static int nixio_file_close(lua_State *L) {
244 int *fdp = luaL_checkudata(L, 1, NIXIO_FILE_META);
245 luaL_argcheck(L, *fdp != -1, 1, "invalid file object");
249 } while (res == -1 && errno == EINTR);
251 return nixio__pstatus(L, !res);
254 static int nixio_file__gc(lua_State *L) {
255 int *fdp = luaL_checkudata(L, 1, NIXIO_FILE_META);
260 } while (res == -1 && errno == EINTR);
267 * string representation
269 static int nixio_file__tostring(lua_State *L) {
270 lua_pushfstring(L, "nixio file %d", nixio__tofd(L, 1));
275 static const luaL_reg M[] = {
276 {"write", nixio_file_write},
277 {"read", nixio_file_read},
278 {"tell", nixio_file_tell},
279 {"seek", nixio_file_seek},
280 {"sync", nixio_file_sync},
281 {"lock", nixio_file_lock},
282 {"close", nixio_file_close},
283 {"__gc", nixio_file__gc},
284 {"__tostring", nixio_file__tostring},
289 static const luaL_reg R[] = {
291 {"open", nixio_open},
292 {"open_flags", nixio_open_flags},
293 {"pipe", nixio_pipe},
297 void nixio_open_file(lua_State *L) {
298 luaL_register(L, NULL, R);
300 luaL_newmetatable(L, NIXIO_FILE_META);
301 luaL_register(L, NULL, M);
302 lua_pushvalue(L, -1);
303 lua_setfield(L, -2, "__index");
304 lua_setfield(L, -2, "meta_file");