root/lang/cplusplus/llv8call/trunk/ext/socket/socket.cc @ 21401

Revision 21401, 21.1 kB (checked in by tokuhirom, 5 years ago)

oops. why i commit this code yesterday?

Line 
1// The MIT License
2//
3// Copyright (c) 2008 Tokuhiro Matsuno
4//
5// Permission is hereby granted, free of charge, to any person obtaining a copy
6// of this software and associated documentation files (the "Software"), to deal
7// in the Software without restriction, including without limitation the rights
8// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9// copies of the Software, and to permit persons to whom the Software is
10// furnished to do so, subject to the following conditions:
11//
12// The above copyright notice and this permission notice shall be included in
13// all copies or substantial portions of the Software.
14//
15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21// THE SOFTWARE.
22
23#include <v8.h>
24#include <cstdio>
25#include <cstdlib>
26#include <memory.h>
27#include <errno.h>
28#include "v8ext.h"
29#include <llv8-macros.h>
30#ifndef _WIN32
31#  include <sys/socket.h>
32#  include <sys/types.h>
33#  include <netinet/in.h>
34#  include <arpa/inet.h>
35#  include <sys/un.h>
36#  include <unistd.h>
37#  include <sys/param.h>
38#  include <netdb.h>
39#endif
40
41typedef union sock_addr {
42    struct sockaddr_in in;
43#if defined(AF_UNIX)
44    struct sockaddr_un un;
45#endif
46#if defined(AF_INET6)
47    struct sockaddr_in6 in6;
48#endif
49} sock_addr_t;
50
51/** DESCRIPTION:
52 *
53 * low level socket class.
54 *
55 * Design of this class is inspired from python's socket class.
56 *
57 */
58
59#define EXTERNAL_SOCKET() int sock = (int) args.This()->GetInternalField(0)->Int32Value()
60
61using namespace v8;
62
63static inline Handle<Value> throw_stderr(const char *msg) {
64    std::string buf(msg);
65    buf += " error: ";
66    buf += strerror(errno);
67    return ThrowException(String::New(buf.c_str()));
68}
69
70static inline v8::Handle<v8::Object> socket_namespace() {
71        return v8::Context::GetCurrent()->Global()
72                      ->Get(v8::String::New("org"))->ToObject()
73                      ->Get(v8::String::New("coderepos"))->ToObject()
74                      ->Get(v8::String::New("socket"))->ToObject();
75}
76
77// TODO: support AF_UNIX
78static inline Handle<Array> _makeaddr(sockaddr & addr) {
79    Handle<Array> ret = Array::New(2);
80    switch (addr.sa_family) {
81#if defined(AF_UNIX)
82    case AF_UNIX:
83        {
84            sockaddr_un * addr_un = (sockaddr_un*)&addr;
85            ret->Set(Int32::New(0), String::New(addr_un->sun_path));
86        }
87        break;
88#endif
89#if defined(AF_INET6)
90    case AF_INET6:
91        {
92            char buf[NI_MAXHOST];
93            if (getnameinfo(&addr, sizeof(sockaddr_in6), buf, sizeof(buf), NULL, 0, NI_NUMERICHOST)) {
94                throw_stderr(__func__);
95                return ret;
96            }
97            sockaddr_in6 * addr_in6 = (sockaddr_in6*)&addr;
98            ret->Set(Int32::New(0), String::New(buf));
99            ret->Set(Int32::New(1), Int32::New(ntohs(addr_in6->sin6_port)));
100        }
101        break;
102#endif
103    case AF_INET:
104        {
105            char buf[NI_MAXHOST];
106            if (getnameinfo(&addr, sizeof(sockaddr_in), buf, sizeof(buf), NULL, 0, NI_NUMERICHOST)) {
107                throw_stderr(__func__);
108                return ret;
109            }
110            sockaddr_in * addr_in = (sockaddr_in*)&addr;
111            ret->Set(Int32::New(0), String::New(buf));
112            ret->Set(Int32::New(1), Int32::New(ntohs(addr_in->sin_port)));
113        }
114        break;
115    default:
116        ThrowException(String::New("This family does not supported yet"));
117        return ret;
118    }
119    return ret;
120}
121
122// TODO: support unix domain socket
123static inline void _gen_sockaddr(Handle<Array> &args, int family, sock_addr_t* addr_ret, socklen_t * len) {
124    switch (family) {
125#if defined(AF_UNIX)
126    case AF_UNIX:
127        {
128            if (args->Length() != 1) {
129                ThrowException(String::New("invalid args: AF_UNIX => (socket file)"));
130                return;
131            }
132            struct sockaddr_un *addr = (struct sockaddr_un*)addr_ret;
133            memset(addr, 0, sizeof(sockaddr_un)); // clear
134
135            String::Utf8Value path(args->Get(Int32::New(0)));
136            if ((unsigned int)path.length() >= sizeof(addr->sun_path)) {
137                ThrowException(String::New("path too long"));
138                return;
139            }
140            addr->sun_family = AF_UNIX;
141            memcpy(addr->sun_path, *path, path.length());
142            addr->sun_path[path.length()] = '\0';
143            *len = path.length() + (sizeof(*addr) - sizeof(addr->sun_path));
144        }
145        break;
146#endif
147#if defined(AF_INET6)
148    case AF_INET6:
149        {
150            if (args->Length() != 2) {
151                ThrowException(String::New("invalid args: AF_INET => (host, port)"));
152                return;
153            }
154            String::Utf8Value host(args->Get(Int32::New(0)));
155            int32_t port = args->Get(Int32::New(1))->Int32Value();
156
157            struct sockaddr_in6 *addr = (struct sockaddr_in6*)addr_ret;
158            memset(addr, 0, sizeof(*addr)); // clear
159            addr->sin6_family = AF_INET6;
160            int pton_ret = inet_pton(AF_INET6, *host, addr->sin6_addr.s6_addr);
161            if (pton_ret == 0) {
162                ThrowException(String::New("invalid ip form"));
163                return;
164            } else if (pton_ret == -1) {
165                ThrowException(String::New("unknown protocol family"));
166                return;
167            }
168            addr->sin6_port = htons((short)port);
169            *len = sizeof(*addr);
170        }
171        break;
172#endif
173    case AF_INET:
174        {
175            if (args->Length() != 2) {
176                ThrowException(String::New("invalid args: AF_INET => (host, port)"));
177                return;
178            }
179            String::Utf8Value host(args->Get(Int32::New(0)));
180            int32_t port = args->Get(Int32::New(1))->Int32Value();
181
182            struct sockaddr_in *addr = (struct sockaddr_in*)addr_ret;
183            memset(addr, 0, sizeof(*addr)); // clear
184            addr->sin_family = AF_INET;
185            in_addr_t hostinfo = inet_addr(*host);
186            if (hostinfo == INADDR_NONE) {
187                ThrowException(String::New("invalid ip"));
188                return;
189            }
190            addr->sin_addr.s_addr = hostinfo;
191            addr->sin_port = htons((short)port);
192            *len = sizeof(*addr);
193        }
194        break;
195    default:
196        fprintf(stderr, "unknown family");
197        abort();
198    }
199}
200
201
202FUNCTION(_open)
203    // USAGE: new Socket(Socket.AF_INET, Socket.SOCK_STREAM)
204    if (args.Length() == 5 && args[0]->IsExternal()) {
205        args.This()->SetInternalField(0, args[1]);
206        args.This()->Set(String::New("family"), args[2]);
207        args.This()->Set(String::New("type"),   args[3]);
208        args.This()->Set(String::New("proto"),  args[4]);
209        return args.This();
210    } else {
211        ARG_BETWEEN(0, 3);
212        ARG_int(family, 0);
213        ARG_int(type,   1);
214        ARG_int(protocol,  2);
215
216        if (args.Length() < 1) {
217            family = AF_INET;
218        }
219        if (args.Length() < 2) {
220            type = SOCK_STREAM;
221        }
222        if (args.Length() < 3) {
223            protocol = 0;
224        }
225
226        int desc = socket(family, type, protocol);
227        if (desc != -1) {
228            args.This()->SetInternalField(0, Int32::New(desc));
229            args.This()->Set(String::New("family"), Int32::New(family));
230            args.This()->Set(String::New("type"),   Int32::New(type));
231            args.This()->Set(String::New("proto"),  Int32::New(protocol));
232            return args.This();
233        } else {
234            return ThrowException(String::New("cannot open socket"));
235        }
236    }
237END
238
239FUNCTION(_bind)
240    EXTERNAL_SOCKET();
241    sock_addr_t addr;
242    socklen_t len;
243    int family = args.This()->Get(String::New("family"))->Int32Value();
244    ARG_array(addrsrc, 0);
245    _gen_sockaddr(addrsrc, family, &addr, &len);
246    if (bind(sock, (sockaddr*)&addr, len) == 0) {
247        return Undefined();
248    } else {
249        return throw_stderr("bind error: ");
250    }
251END
252
253FUNCTION(_listen)
254    EXTERNAL_SOCKET();
255    ARG_COUNT(1);
256    ARG_int(backlog, 0);
257    if (listen(sock, backlog) == 0) {
258        return Undefined();
259    } else {
260        return throw_stderr("listen error: ");
261    }
262END
263
264FUNCTION(_gethostname)
265    ARG_COUNT(0);
266    char * buf = new char [_POSIX_HOST_NAME_MAX+1];
267    if (gethostname(buf, _POSIX_HOST_NAME_MAX) == 0) {
268        Handle<String> str = String::New(buf);
269        delete [] buf;
270        return str;
271    } else {
272        delete [] buf;
273        return throw_stderr("gethostname error: ");
274    }
275END
276
277FUNCTION(_gethostbyname)
278    ARG_COUNT(1);
279    ARG_str(hostname, 0);
280    // TODO: gethostbyname_r for thread safe =)
281    struct hostent * ent = gethostbyname(*hostname);
282    if (ent) {
283        if (ent->h_addr_list[0] != NULL) {
284            struct in_addr * addr = (in_addr*)ent->h_addr_list[0];
285            return String::New( inet_ntoa(*addr) );
286        } else {
287            return Undefined();
288        }
289    } else {
290        return throw_stderr("gethostbyname");
291    }
292END
293
294FUNCTION(_getprotobyname)
295    ARG_COUNT(1);
296    ARG_str(protoname, 0);
297    struct protoent * ent = getprotobyname(*protoname);
298    if (ent) {
299        return Uint32::New( ent->p_proto );
300    } else {
301        return throw_stderr("getprotobyname");
302    }
303END
304
305FUNCTION(_accept)
306    EXTERNAL_SOCKET();
307    ARG_COUNT(0);
308    struct sockaddr addr;
309    socklen_t len = sizeof(addr);
310    int newsock = accept(sock, &addr, &len);
311    if (newsock >= 0) {
312        Handle<Value> argv[5];
313        argv[0] = External::New(&len); // dummy field
314        argv[1] = Int32::New(newsock);
315        argv[2] = args.This()->Get(String::New("family"));
316        argv[3] = args.This()->Get(String::New("type"));
317        argv[4] = args.This()->Get(String::New("proto"));
318        return Handle<Function>::Cast( socket_namespace()->Get(String::New("Socket")) )->NewInstance(5, argv);
319    } else {
320        return throw_stderr("accept error: ");
321    }
322END
323
324FUNCTION(_connect)
325    EXTERNAL_SOCKET();
326    sock_addr_t addr;
327    socklen_t len;
328    int family = args.This()->Get(String::New("family"))->Int32Value();
329    ARG_array(addrsrc, 0);
330    _gen_sockaddr(addrsrc, family, &addr, &len);
331    if (connect(sock, (sockaddr*)&addr, len) == 0) {
332        return Undefined();
333    } else {
334        return throw_stderr("connect error: ");
335    }
336END
337
338FUNCTION(_recv)
339    EXTERNAL_SOCKET();
340    ARG_BETWEEN(1, 2);
341    ARG_int(len, 0);
342    int _flags = 0;
343    if (args.Length() == 2) {
344        ARG_int(flags, 1);
345        _flags = flags;
346    }
347    char * buf = new char [len+1];
348    assert(sock);
349    ssize_t size = recv(sock, buf, len, _flags);
350    if (size >= 0) {
351        Handle<String> res = String::New(buf, size);
352        delete [] buf;
353        return res;
354    } else {
355        delete [] buf;
356        return throw_stderr("recv error: ");
357    }
358END
359
360FUNCTION(_recvfrom)
361    EXTERNAL_SOCKET();
362    ARG_BETWEEN(1, 2);
363    ARG_int(buflen, 0);
364    int _flags = 0;
365    if (args.Length() == 2) {
366        ARG_int(flags, 1);
367        _flags = flags;
368    }
369    char * buf = new char [buflen];
370    struct sockaddr addr;
371    socklen_t addrlen = sizeof(sockaddr);
372    ssize_t size = recvfrom(sock, buf, buflen, _flags, &addr, &addrlen);
373    if (size >= 0) {
374        Handle<Array> ret = Array::New(2);
375        ret->Set(Int32::New(0), String::New(buf, size));
376        ret->Set(Int32::New(1), _makeaddr(addr));
377        delete [] buf;
378        return ret;
379    } else {
380        delete [] buf;
381        return throw_stderr("recvfrom error: ");
382    }
383END
384
385FUNCTION(_send)
386    // @ret Returns the number of bytes sent.
387    EXTERNAL_SOCKET();
388    ARG_BETWEEN(1, 2);
389    ARG_str(str, 0);
390    int _flags = 0;
391    if (args.Length() == 2) {
392        ARG_int(flags, 1);
393        _flags = flags;
394    }
395    ssize_t size = send(sock, *str, str.length(), _flags);
396    if (size >= 0) {
397        return Int32::New(size);
398    } else {
399        return throw_stderr("send error: ");
400    }
401END
402
403FUNCTION(_sendto)
404    // @prototype sock.sendto(str, [flags, ] addr);
405    // @ret Returns the number of bytes sent.
406    EXTERNAL_SOCKET();
407    ARG_BETWEEN(2, 3);
408    ARG_str(str, 0);
409    int _flags = 0;
410    Handle<Array> addrsrc;
411    if (args.Length() == 3) {
412        ARG_int(flags, 1);
413        _flags = flags;
414        addrsrc = Handle<Array>::Cast(args[2]);
415    } else {
416        addrsrc = Handle<Array>::Cast(args[1]);
417    }
418    sock_addr_t addr;
419    socklen_t len;
420    int family = args.This()->Get(String::New("family"))->Int32Value();
421    _gen_sockaddr(addrsrc, family, &addr, &len);
422    ssize_t size = sendto(sock, *str, str.length(), _flags, (sockaddr*)&addr, len);
423    if (size >= 0) {
424        return Int32::New(size);
425    } else {
426        return throw_stderr("send error: ");
427    }
428END
429
430FUNCTION(_getsockname)
431    EXTERNAL_SOCKET();
432    ARG_COUNT(0);
433    sockaddr addr;
434    socklen_t len = sizeof(sockaddr);
435    if (getsockname(sock, &addr, &len) == 0) {
436        return _makeaddr(addr);
437    } else {
438        return throw_stderr("getsockname");
439    }
440END
441
442FUNCTION(_getpeername)
443    EXTERNAL_SOCKET();
444    ARG_COUNT(0);
445    sockaddr addr;
446    socklen_t len = sizeof(sockaddr);
447    if (getpeername(sock, &addr, &len) == 0) {
448        return _makeaddr(addr);
449    } else {
450        return throw_stderr("getpeername");
451    }
452END
453
454FUNCTION(_fileno)
455    EXTERNAL_SOCKET();
456    ARG_COUNT(0);
457    return Uint32::New(sock);
458END
459
460FUNCTION(_close)
461    EXTERNAL_SOCKET();
462    ARG_COUNT(0);
463    if (close(sock) >= 0) {
464        return Undefined();
465    } else {
466        return throw_stderr("close error: ");
467    }
468END
469
470FUNCTION(_inet_aton)
471    ARG_COUNT(1);
472    ARG_str(ip, 0);
473    in_addr addr;
474    if (inet_aton(*ip, &addr) == 1) {
475        return Uint32::New(addr.s_addr);
476    } else {
477        return throw_stderr("inet_aton");
478    }
479END
480
481FUNCTION(_inet_ntoa)
482    ARG_COUNT(1);
483    ARG_uint(ip, 0);
484    in_addr addr;
485    addr.s_addr = ip;
486    char * buf = inet_ntoa(addr);
487    if (buf) {
488        return String::New(buf);
489    } else {
490        return throw_stderr("inet_ntoa");
491    }
492END
493
494FUNCTION(_socketpair)
495    // @prototype socket.socketpair([family[, type[, proto]]])
496    ARG_BETWEEN(0, 3);
497    ARG_int(family, 0);
498    ARG_int(type,   1);
499    ARG_int(protocol,  2);
500
501    if (args.Length() < 1) {
502#if defined(AF_UNIX)
503        family = AF_UNIX;
504#else
505        family = AF_INET;
506#endif
507    }
508    if (args.Length() < 2) {
509        type = SOCK_STREAM;
510    }
511    if (args.Length() < 3) {
512        protocol = 0;
513    }
514
515    int socket_vector[2];
516    if (socketpair(family, type, protocol, socket_vector) == 0) {
517        Handle<Array> ret = Array::New(2);
518        for (int i=0; i<2; i++) {
519            Handle<Value> argv[5];
520            argv[0] = External::New((void*)&family); // dummy field
521            argv[1] = Int32::New(socket_vector[i]);
522            argv[2] = Int32::New(family);
523            argv[3] = Int32::New(type);
524            argv[4] = Int32::New(protocol);
525            Handle<Object> obj = Handle<Function>::Cast( socket_namespace()->Get(String::New("Socket")) )->NewInstance(5, argv);
526            ret->Set(Int32::New(i), obj);
527        }
528        return ret;
529    } else {
530        return throw_stderr("inet_aton");
531    }
532END
533
534FUNCTION(_ntohl)
535    ARG_COUNT(1);
536    ARG_int(n, 0);
537    return Uint32::New(ntohl(n));
538END
539
540FUNCTION(_ntohs)
541    ARG_COUNT(1);
542    ARG_int(n, 0);
543    return Uint32::New(ntohs(n));
544END
545
546FUNCTION(_htons)
547    ARG_COUNT(1);
548    ARG_int(n, 0);
549    return Uint32::New(htons(n));
550END
551
552FUNCTION(_htonl)
553    ARG_COUNT(1);
554    ARG_int(n, 0);
555    return Uint32::New(htonl(n));
556END
557
558FUNCTION(_setsockopt)
559    EXTERNAL_SOCKET();
560    ARG_COUNT(3);
561    ARG_int(level, 0);
562    ARG_int(optname, 1);
563    ARG_int(value, 2);
564    if (setsockopt(sock, level, optname, &value, sizeof(int)) == 0) {
565        return Undefined();
566    } else {
567        return throw_stderr("setsockopt");
568    }
569END
570
571FUNCTION(_getsockopt)
572    // @prototype getsockopt(level, optname[, buflen])
573    EXTERNAL_SOCKET();
574    ARG_BETWEEN(2, 3);
575    ARG_int(level, 0);
576    ARG_int(optname, 1);
577    if (args.Length() == 3) {
578        ARG_int(buflen, 2);
579        char * buf = new char [buflen];
580        if (getsockopt(sock, level, optname, buf, (socklen_t*)&buflen) == 0) {
581            return String::New(buf, buflen);
582        } else {
583            return throw_stderr("getsockopt");
584        }
585    } else {
586        unsigned int buf;
587        int buflen = sizeof(buf);
588        if (getsockopt(sock, level, optname, &buf, (socklen_t*)&buflen) == 0) {
589            return Uint32::New(buf);
590        } else {
591            return throw_stderr("getsockopt");
592        }
593    }
594END
595
596MODULE()
597    {
598        CLASS_WITH_CONSTRUCTOR(_open);
599
600        BIND_CI("SOCK_STREAM",    SOCK_STREAM);
601        BIND_CI("SOCK_DGRAM",     SOCK_DGRAM);
602        BIND_CI("SOCK_RAW",       SOCK_RAW);
603        BIND_CI("SOCK_RDM",       SOCK_RDM);
604        BIND_CI("SOCK_SEQPACKET", SOCK_SEQPACKET);
605
606#if defined(AF_UNIX)
607        BIND_CI("AF_UNIX",        AF_UNIX);
608#endif
609        BIND_CI("AF_INET",        AF_INET);
610#if defined(AF_INET6)
611        BIND_CI("AF_INET6",       AF_INET6);
612#endif
613
614        // grep '"SOL_' Modules/socketmodule.c|perl -lne 'print "#if defined($1)\n        BIND_CI(\"$1\", $1)\n#endif" if /"(SOL_\w+)"/'
615#if defined(SOL_HCI)
616        BIND_CI("SOL_HCI", SOL_HCI)
617#endif
618#if defined(SOL_SOCKET)
619        BIND_CI("SOL_SOCKET", SOL_SOCKET)
620#endif
621#if defined(SOL_IP)
622        BIND_CI("SOL_IP", SOL_IP)
623#endif
624#if defined(SOL_IP)
625        BIND_CI("SOL_IP", SOL_IP)
626#endif
627#if defined(SOL_IPX)
628        BIND_CI("SOL_IPX", SOL_IPX)
629#endif
630#if defined(SOL_AX25)
631        BIND_CI("SOL_AX25", SOL_AX25)
632#endif
633#if defined(SOL_ATALK)
634        BIND_CI("SOL_ATALK", SOL_ATALK)
635#endif
636#if defined(SOL_NETROM)
637        BIND_CI("SOL_NETROM", SOL_NETROM)
638#endif
639#if defined(SOL_ROSE)
640        BIND_CI("SOL_ROSE", SOL_ROSE)
641#endif
642#if defined(SOL_TCP)
643        BIND_CI("SOL_TCP", SOL_TCP)
644#endif
645#if defined(SOL_TCP)
646        BIND_CI("SOL_TCP", SOL_TCP)
647#endif
648#if defined(SOL_UDP)
649        BIND_CI("SOL_UDP", SOL_UDP)
650#endif
651#if defined(SOL_UDP)
652        BIND_CI("SOL_UDP", SOL_UDP)
653#endif
654
655        // perl -lne 'print "#if defined($1)\n        BIND_CI(\"$1\", $1)\n#endif" if /"(SO_\w+)"/'  Modules/socketmodule.c
656#if defined(SO_DEBUG)
657        BIND_CI("SO_DEBUG", SO_DEBUG)
658#endif
659#if defined(SO_ACCEPTCONN)
660        BIND_CI("SO_ACCEPTCONN", SO_ACCEPTCONN)
661#endif
662#if defined(SO_REUSEADDR)
663        BIND_CI("SO_REUSEADDR", SO_REUSEADDR)
664#endif
665#if defined(SO_EXCLUSIVEADDRUSE)
666        BIND_CI("SO_EXCLUSIVEADDRUSE", SO_EXCLUSIVEADDRUSE)
667#endif
668#if defined(SO_KEEPALIVE)
669        BIND_CI("SO_KEEPALIVE", SO_KEEPALIVE)
670#endif
671#if defined(SO_DONTROUTE)
672        BIND_CI("SO_DONTROUTE", SO_DONTROUTE)
673#endif
674#if defined(SO_BROADCAST)
675        BIND_CI("SO_BROADCAST", SO_BROADCAST)
676#endif
677#if defined(SO_USELOOPBACK)
678        BIND_CI("SO_USELOOPBACK", SO_USELOOPBACK)
679#endif
680#if defined(SO_LINGER)
681        BIND_CI("SO_LINGER", SO_LINGER)
682#endif
683#if defined(SO_OOBINLINE)
684        BIND_CI("SO_OOBINLINE", SO_OOBINLINE)
685#endif
686#if defined(SO_REUSEPORT)
687        BIND_CI("SO_REUSEPORT", SO_REUSEPORT)
688#endif
689#if defined(SO_SNDBUF)
690        BIND_CI("SO_SNDBUF", SO_SNDBUF)
691#endif
692#if defined(SO_RCVBUF)
693        BIND_CI("SO_RCVBUF", SO_RCVBUF)
694#endif
695#if defined(SO_SNDLOWAT)
696        BIND_CI("SO_SNDLOWAT", SO_SNDLOWAT)
697#endif
698#if defined(SO_RCVLOWAT)
699        BIND_CI("SO_RCVLOWAT", SO_RCVLOWAT)
700#endif
701#if defined(SO_SNDTIMEO)
702        BIND_CI("SO_SNDTIMEO", SO_SNDTIMEO)
703#endif
704#if defined(SO_RCVTIMEO)
705        BIND_CI("SO_RCVTIMEO", SO_RCVTIMEO)
706#endif
707#if defined(SO_ERROR)
708        BIND_CI("SO_ERROR", SO_ERROR)
709#endif
710#if defined(SO_TYPE)
711        BIND_CI("SO_TYPE", SO_TYPE)
712#endif
713
714        BIND_CM("gethostname",    _gethostname);
715        BIND_CM("gethostbyname",  _gethostbyname);
716        BIND_CM("getprotobyname", _getprotobyname);
717        BIND_CM("inet_aton",      _inet_aton);
718        BIND_CM("inet_ntoa",      _inet_ntoa);
719        BIND_CM("socketpair",     _socketpair);
720        BIND_CM("ntohl",          _ntohl);
721        BIND_CM("ntohs",          _ntohs);
722        BIND_CM("htons",          _htons);
723        BIND_CM("htonl",          _htonl);
724
725        BIND_IM("bind",           _bind);
726        BIND_IM("listen",         _listen);
727        BIND_IM("accept",         _accept);
728        BIND_IM("connect",        _connect);
729        BIND_IM("recv",           _recv);
730        BIND_IM("recvfrom",       _recvfrom);
731        BIND_IM("send",           _send);
732        BIND_IM("sendto",         _sendto);
733        BIND_IM("getsockname",    _getsockname);
734        BIND_IM("getpeername",    _getpeername);
735        BIND_IM("fileno",         _fileno);
736        BIND_IM("setsockopt",     _setsockopt);
737        BIND_IM("getsockopt",     _getsockopt);
738        BIND_IM("close",          _close);
739        // rest function is: 20
740        // getaddrinfo
741        // getfqdn
742        // gethostbyaddr
743        // getnameinfo
744        // getservbyname
745        // getservbyport
746        // fromfd
747        // inet_pton
748        // inet_ntop
749        // getdefaulttimeout
750        // setdefaulttimeout
751        // ioctl
752        // makefile
753        // recvfrom_into
754        // recv_into
755        // sendall
756        // setblocking
757        // settimeout
758        // gettimeout
759        // shutdown
760
761        INTERNALCOUNT(1);
762
763        EXPORT_CLASS("Socket");
764    }
765ENDMODULE
766
Note: See TracBrowser for help on using the browser.