12d5c7df4529661b9869ebbd0e514a255e5d6331
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.
24 #include <sys/types.h>
28 * send() / sendto() helper
30 static int nixio_sock__sendto(lua_State
*L
, int to
) {
31 nixio_sock
*sock
= nixio__checksock(L
);
32 struct sockaddr_storage addr_in
;
34 struct sockaddr_un addr_un
;
36 struct sockaddr
*addr
= NULL
;
42 if (sock
->domain
== AF_INET
|| sock
->domain
== AF_INET6
) {
43 const char *address
= luaL_checkstring(L
, 3);
44 addr
= (struct sockaddr
*)&addr_in
;
45 alen
= sizeof(addr_in
);
48 memset(&naddr
, 0, sizeof(naddr
));
49 strncpy(naddr
.host
, address
, sizeof(naddr
.host
) - 1);
50 naddr
.port
= (uint16_t)luaL_checkinteger(L
, 4);
51 naddr
.family
= sock
->domain
;
53 if (nixio__addr_write(&naddr
, addr
)) {
54 return nixio__perror_s(L
);
59 else if (sock
->domain
== AF_UNIX
) {
61 const char *path
= luaL_checklstring(L
, 3, &pathlen
);
63 addr_un
.sun_family
= AF_UNIX
;
64 luaL_argcheck(L
, pathlen
<= sizeof(addr_un
.sun_path
), 3, "out of range");
65 memcpy(addr_un
.sun_path
, path
, pathlen
);
67 addr
= (struct sockaddr
*)&addr_un
;
68 alen
= sizeof(sa_family_t
) + pathlen
;
75 const char *data
= luaL_checklstring(L
, 2, &len
);
77 if (lua_gettop(L
) > argoff
) {
78 int offset
= luaL_optint(L
, argoff
+ 1, 0);
88 unsigned int wlen
= luaL_optint(L
, argoff
+ 2, len
);
95 sent
= sendto(sock
->fd
, data
, len
, 0, addr
, alen
);
96 } while(sent
== -1 && errno
== EINTR
);
98 lua_pushinteger(L
, sent
);
101 return nixio__perror_s(L
);
108 static int nixio_sock_send(lua_State
*L
) {
109 return nixio_sock__sendto(L
, 0);
113 * sendto(data, address, port)
115 static int nixio_sock_sendto(lua_State
*L
) {
116 return nixio_sock__sendto(L
, 1);
121 * recv() / recvfrom() helper
123 static int nixio_sock__recvfrom(lua_State
*L
, int from
) {
124 nixio_sock
*sock
= nixio__checksock(L
);
125 char buffer
[NIXIO_BUFFERSIZE
];
126 struct sockaddr_storage addr_in
;
128 struct sockaddr_un addr_un
;
130 struct sockaddr
*addr
= NULL
;
132 uint req
= luaL_checkinteger(L
, 2);
135 if (sock
->domain
== AF_INET
|| sock
->domain
== AF_INET6
) {
136 addr
= (from
) ? (struct sockaddr
*)&addr_in
: NULL
;
137 alen
= (from
) ? sizeof(addr_in
) : 0;
140 else if (sock
->domain
== AF_UNIX
) {
141 addr
= (from
) ? (struct sockaddr
*)&addr_un
: NULL
;
142 alen
= (from
) ? sizeof(addr_un
) : 0;
146 /* We limit the readsize to NIXIO_BUFFERSIZE */
147 req
= (req
> NIXIO_BUFFERSIZE
) ? NIXIO_BUFFERSIZE
: req
;
150 readc
= recvfrom(sock
->fd
, buffer
, req
, 0, addr
, &alen
);
151 } while (readc
== -1 && errno
== EINTR
);
155 int e
= WSAGetLastError();
156 if (e
== WSAECONNRESET
|| e
== WSAECONNABORTED
|| e
== WSAESHUTDOWN
) {
163 return nixio__perror_s(L
);
165 lua_pushlstring(L
, buffer
, readc
);
171 if (sock
->domain
== AF_INET
|| sock
->domain
== AF_INET6
) {
173 if (!nixio__addr_parse(&naddr
, (struct sockaddr
*)&addr_in
)) {
174 lua_pushstring(L
, naddr
.host
);
175 lua_pushinteger(L
, naddr
.port
);
182 else if (sock
->domain
== AF_UNIX
&& alen
> sizeof(sa_family_t
)) {
183 /* if first char is non-null then the path is not in the
184 abstract namespace and alen includes the trailing null */
185 if (addr_un
.sun_path
[0])
187 lua_pushlstring(L
, addr_un
.sun_path
, alen
- sizeof(sa_family_t
));
198 static int nixio_sock_recv(lua_State
*L
) {
199 return nixio_sock__recvfrom(L
, 0);
205 static int nixio_sock_recvfrom(lua_State
*L
) {
206 return nixio_sock__recvfrom(L
, 1);
211 static const luaL_reg M
[] = {
212 {"send", nixio_sock_send
},
213 {"sendto", nixio_sock_sendto
},
214 {"recv", nixio_sock_recv
},
215 {"recvfrom",nixio_sock_recvfrom
},
216 {"write", nixio_sock_send
},
217 {"read", nixio_sock_recv
},
221 void nixio_open_io(lua_State
*L
) {
222 lua_pushvalue(L
, -2);
223 luaL_register(L
, NULL
, M
);