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.
28 #include <sys/param.h>
34 #include <sys/sendfile.h>
36 #include <sys/types.h>
37 #include <sys/socket.h>
44 /* guess what sucks... */
47 #include <sys/syscall.h>
49 ssize_t
splice(int __fdin
, __off64_t
*__offin
, int __fdout
,
50 __off64_t
*__offout
, size_t __len
, unsigned int __flags
) {
52 return syscall(__NR_splice
, __fdin
, __offin
, __fdout
, __offout
, __len
, __flags
);
66 #undef SPLICE_F_NONBLOCK
69 #define SPLICE_F_MOVE 1
70 #define SPLICE_F_NONBLOCK 2
71 #define SPLICE_F_MORE 4
73 #endif /* __UCLIBC__ */
76 * splice(fd_in, fd_out, length, flags)
78 static int nixio_splice(lua_State
*L
) {
79 int fd_in
= nixio__checkfd(L
, 1);
80 int fd_out
= nixio__checkfd(L
, 2);
81 size_t len
= luaL_checkinteger(L
, 3);
82 int flags
= luaL_optinteger(L
, 4, 0);
86 spliced
= splice(fd_in
, NULL
, fd_out
, NULL
, len
, flags
);
87 } while (spliced
== -1 && errno
== EINTR
);
90 return nixio__perror(L
);
93 lua_pushinteger(L
, spliced
);
98 * Translate splice flags to integer
100 static int nixio_splice_flags(lua_State
*L
) {
101 const int j
= lua_gettop(L
);
103 for (int i
=1; i
<=j
; i
++) {
104 const char *flag
= luaL_checkstring(L
, i
);
105 if (!strcmp(flag
, "move")) {
106 flags
|= SPLICE_F_MOVE
;
107 } else if (!strcmp(flag
, "nonblock")) {
108 flags
|= SPLICE_F_NONBLOCK
;
109 } else if (!strcmp(flag
, "more")) {
110 flags
|= SPLICE_F_MORE
;
112 return luaL_argerror(L
, i
, "supported values: "
113 "move, nonblock, more");
116 lua_pushinteger(L
, flags
);
121 #endif /* SPLICE_F_MOVE */
122 #endif /* _GNU_SOURCE */
125 * sendfile(outfd, infd, length)
127 static int nixio_sendfile(lua_State
*L
) {
128 int sock
= nixio__checksockfd(L
);
129 int infd
= nixio__checkfd(L
, 2);
130 size_t len
= luaL_checkinteger(L
, 3);
135 spliced
= sendfile(sock
, infd
, NULL
, len
);
136 } while (spliced
== -1 && errno
== EINTR
);
139 return nixio__perror(L
);
143 const off_t offset
= lseek(infd
, 0, SEEK_CUR
);
147 r
= sendfile(infd
, sock
, offset
, (off_t
*)&len
, NULL
, 0);
149 r
= sendfile(infd
, sock
, offset
, len
, NULL
, &spliced
, 0);
151 } while (r
== -1 && errno
== EINTR
);
154 return nixio__perror(L
);
158 lua_pushinteger(L
, spliced
);
163 static const luaL_reg R
[] = {
166 {"splice", nixio_splice
},
167 {"splice_flags", nixio_splice_flags
},
170 {"sendfile", nixio_sendfile
},
175 void nixio_open_splice(lua_State
*L
) {
176 luaL_register(L
, NULL
, R
);
179 #else /* __WINNT__ */
181 void nixio_open_splice(lua_State
*L
) {
184 #endif /* !__WINNT__ */