482752522737682cbad8e83203b605fd83446ff8
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
);
35 if (lua_isnoneornil(L
, 2)) {
37 } else if (lua_isnumber(L
, 2)) {
38 flags
= lua_tointeger(L
, 2);
39 } else if (lua_isstring(L
, 2)) {
40 const char *str
= lua_tostring(L
, 2);
41 if (!strcmp(str
, "r")) {
43 } else if (!strcmp(str
, "r+")) {
45 } else if (!strcmp(str
, "w")) {
46 flags
= O_WRONLY
| O_CREAT
| O_TRUNC
;
47 } else if (!strcmp(str
, "w+")) {
48 flags
= O_RDWR
| O_CREAT
| O_TRUNC
;
49 } else if (!strcmp(str
, "a")) {
50 flags
= O_WRONLY
| O_CREAT
| O_APPEND
;
51 } else if (!strcmp(str
, "a+")) {
52 flags
= O_RDWR
| O_CREAT
| O_APPEND
;
54 return luaL_argerror(L
, 2, "supported values: r, r+, w, w+, a, a+");
57 return luaL_argerror(L
, 2, "open flags or string expected");
63 fd
= open(filename
, flags
, nixio__check_mode(L
, 3, 0666));
64 } while (fd
== -1 && errno
== EINTR
);
66 return nixio__perror(L
);
69 int *udata
= lua_newuserdata(L
, sizeof(int));
71 return luaL_error(L
, "out of memory");
76 luaL_getmetatable(L
, NIXIO_FILE_META
);
77 lua_setmetatable(L
, -2);
82 static int nixio_open_flags(lua_State
*L
) {
84 const int j
= lua_gettop(L
);
85 for (int i
=1; i
<=j
; i
++) {
86 const char *flag
= luaL_checkstring(L
, i
);
87 if (!strcmp(flag
, "append")) {
89 } else if (!strcmp(flag
, "creat")) {
91 } else if (!strcmp(flag
, "excl")) {
93 } else if (!strcmp(flag
, "nonblock") || !strcmp(flag
, "ndelay")) {
97 } else if (!strcmp(flag
, "sync")) {
101 } else if (!strcmp(flag
, "trunc")) {
103 } else if (!strcmp(flag
, "rdonly")) {
105 } else if (!strcmp(flag
, "wronly")) {
107 } else if (!strcmp(flag
, "rdwr")) {
110 return luaL_argerror(L
, i
, "supported values: append, creat, "
111 "excl, nonblock, ndelay, sync, trunc");
114 lua_pushinteger(L
, mode
);
118 static int nixio_dup(lua_State
*L
) {
119 int oldfd
= nixio__checkfd(L
, 1);
120 int newfd
= (lua_gettop(L
) > 1) ? nixio__checkfd(L
, 2) : -1;
121 int stat
= (newfd
== -1) ? dup(oldfd
) : dup2(oldfd
, newfd
);
124 return nixio__perror(L
);
126 int *udata
= lua_newuserdata(L
, sizeof(int));
128 return luaL_error(L
, "out of memory");
132 luaL_getmetatable(L
, NIXIO_FILE_META
);
133 lua_setmetatable(L
, -2);
138 static int nixio_pipe(lua_State
*L
) {
139 int pipefd
[2], *udata
;
141 return nixio__perror(L
);
144 luaL_getmetatable(L
, NIXIO_FILE_META
);
145 udata
= lua_newuserdata(L
, sizeof(int));
147 return luaL_error(L
, "out of memory");
151 lua_pushvalue(L
, -2);
152 lua_setmetatable(L
, -2);
155 udata
= lua_newuserdata(L
, sizeof(int));
157 return luaL_error(L
, "out of memory");
161 lua_pushvalue(L
, -3);
162 lua_setmetatable(L
, -2);
167 static int nixio_file_write(lua_State
*L
) {
168 int fd
= nixio__checkfd(L
, 1);
171 const char *data
= luaL_checklstring(L
, 2, &len
);
173 if (lua_gettop(L
) > 2) {
174 int offset
= luaL_optint(L
, 3, 0);
184 unsigned int wlen
= luaL_optint(L
, 4, len
);
191 sent
= write(fd
, data
, len
);
192 } while(sent
== -1 && errno
== EINTR
);
194 lua_pushinteger(L
, sent
);
197 return nixio__perror(L
);
201 static int nixio_file_read(lua_State
*L
) {
202 int fd
= nixio__checkfd(L
, 1);
203 char buffer
[NIXIO_BUFFERSIZE
];
204 uint req
= luaL_checkinteger(L
, 2);
207 /* We limit the readsize to NIXIO_BUFFERSIZE */
208 req
= (req
> NIXIO_BUFFERSIZE
) ? NIXIO_BUFFERSIZE
: req
;
211 readc
= read(fd
, buffer
, req
);
212 } while (readc
== -1 && errno
== EINTR
);
215 return nixio__perror(L
);
217 lua_pushlstring(L
, buffer
, readc
);
223 static int nixio_file_seek(lua_State
*L
) {
224 int fd
= nixio__checkfd(L
, 1);
225 off_t len
= (off_t
)luaL_checknumber(L
, 2);
227 const char *whstr
= luaL_optlstring(L
, 3, "set", NULL
);
228 if (!strcmp(whstr
, "set")) {
230 } else if (!strcmp(whstr
, "cur")) {
232 } else if (!strcmp(whstr
, "end")) {
235 return luaL_argerror(L
, 3, "supported values: set, cur, end");
237 len
= lseek(fd
, len
, whence
);
239 return nixio__perror(L
);
241 lua_pushnumber(L
, len
);
246 static int nixio_file_tell(lua_State
*L
) {
247 int fd
= nixio__checkfd(L
, 1);
248 off_t pos
= lseek(fd
, 0, SEEK_CUR
);
250 return nixio__perror(L
);
252 lua_pushnumber(L
, pos
);
257 static int nixio_file_stat(lua_State
*L
) {
259 if (fstat(nixio__checkfd(L
, 1), &buf
)) {
260 return nixio__perror(L
);
262 nixio__push_stat(L
, &buf
);
263 if (lua_isstring(L
, 2)) {
264 lua_getfield(L
, -1, lua_tostring(L
, 2));
270 static int nixio_file_sync(lua_State
*L
) {
271 int fd
= nixio__checkfd(L
, 1);
273 #if (!defined BSD && !defined __WINNT__)
274 int dataonly
= lua_toboolean(L
, 2);
276 stat
= (dataonly
) ? fdatasync(fd
) : fsync(fd
);
277 } while (stat
== -1 && errno
== EINTR
);
278 return nixio__pstatus(L
, !stat
);
282 } while (stat
== -1 && errno
== EINTR
);
283 return nixio__pstatus(L
, !stat
);
287 static int nixio_file_lock(lua_State
*L
) {
288 int fd
= nixio__checkfd(L
, 1);
289 const char *flag
= luaL_checkstring(L
, 2);
290 off_t len
= (off_t
)luaL_optnumber(L
, 3, 0);
294 if (!strcmp(flag
, "lock")) {
296 } else if (!strcmp(flag
, "tlock")) {
298 } else if (!strcmp(flag
, "ulock")) {
300 } else if (!strcmp(flag
, "test")) {
303 return luaL_argerror(L
, 2,
304 "supported values: lock, tlock, ulock, test");
308 stat
= lockf(fd
, cmd
, len
);
309 } while (stat
== -1 && errno
== EINTR
);
311 return nixio__pstatus(L
, !stat
);
314 static int nixio_file_close(lua_State
*L
) {
315 int *fdp
= luaL_checkudata(L
, 1, NIXIO_FILE_META
);
316 luaL_argcheck(L
, *fdp
!= -1, 1, "invalid file object");
320 } while (res
== -1 && errno
== EINTR
);
322 return nixio__pstatus(L
, !res
);
325 static int nixio_file__gc(lua_State
*L
) {
326 int *fdp
= luaL_checkudata(L
, 1, NIXIO_FILE_META
);
331 } while (res
== -1 && errno
== EINTR
);
338 * string representation
340 static int nixio_file__tostring(lua_State
*L
) {
341 lua_pushfstring(L
, "nixio file %d", nixio__tofd(L
, 1));
346 static const luaL_reg M
[] = {
347 {"write", nixio_file_write
},
348 {"read", nixio_file_read
},
349 {"tell", nixio_file_tell
},
350 {"seek", nixio_file_seek
},
351 {"stat", nixio_file_stat
},
352 {"sync", nixio_file_sync
},
353 {"lock", nixio_file_lock
},
354 {"close", nixio_file_close
},
355 {"__gc", nixio_file__gc
},
356 {"__tostring", nixio_file__tostring
},
361 static const luaL_reg R
[] = {
363 {"open", nixio_open
},
364 {"open_flags", nixio_open_flags
},
365 {"pipe", nixio_pipe
},
369 void nixio_open_file(lua_State
*L
) {
370 luaL_register(L
, NULL
, R
);
372 luaL_newmetatable(L
, NIXIO_FILE_META
);
373 luaL_register(L
, NULL
, M
);
374 lua_pushvalue(L
, -1);
375 lua_setfield(L
, -2, "__index");
377 int *uin
= lua_newuserdata(L
, sizeof(int));
378 int *uout
= lua_newuserdata(L
, sizeof(int));
379 int *uerr
= lua_newuserdata(L
, sizeof(int));
381 if (!uin
|| !uout
|| !uerr
) {
382 luaL_error(L
, "out of memory");
386 *uout
= STDOUT_FILENO
;
387 *uerr
= STDERR_FILENO
;
389 for (int i
= -4; i
< -1; i
++) {
390 lua_pushvalue(L
, -4);
391 lua_setmetatable(L
, i
);
394 lua_setfield(L
, -5, "stderr");
395 lua_setfield(L
, -4, "stdout");
396 lua_setfield(L
, -3, "stdin");
397 lua_setfield(L
, -2, "meta_file");