summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorYukihiro Matsumoto <matz@ruby-lang.org>1995-04-10 18:36:06 +0900
committerTakashi Kokubun <takashikkbn@gmail.com>2019-08-17 22:09:32 +0900
commitb2420d8ffa4d347a75efbbdc376f4ce65c0eb172 (patch)
treebd40c44d9155d9cb10232a0e962dc1cc221c2c8b /ext
parent11e21a36bc935088f88a7cd1548f8c74c3bf6099 (diff)
version 0.73v0_73
https://cache.ruby-lang.org/pub/ruby/1.0/ruby-0.73.tar.gz Mon Apr 10 18:36:06 1995 Yukihiro Matsumoto (matz@ix-02) * version 0.73 Fri Apr 7 13:51:08 1995 Yukihiro Matsumoto (matz@ix-02) * cons.c->assoc.c: consの余計な機能は外してpairとしての機能だけを 残した.enumerableをincludeするのもやめた. * string.c(esub): 文字列置換イテレータ.perlのs///eの相当する.
Diffstat (limited to 'ext')
-rw-r--r--ext/MANIFEST6
-rw-r--r--ext/Makefile.in40
-rw-r--r--ext/dbm.c441
-rw-r--r--ext/dbm.doc107
-rw-r--r--ext/socket.c761
-rw-r--r--ext/socket.doc227
6 files changed, 1582 insertions, 0 deletions
diff --git a/ext/MANIFEST b/ext/MANIFEST
new file mode 100644
index 0000000..881a97c
--- /dev/null
+++ b/ext/MANIFEST
@@ -0,0 +1,6 @@
+MANIFEST
+Makefile.in
+dbm.c
+dbm.doc
+socket.c
+socket.doc
diff --git a/ext/Makefile.in b/ext/Makefile.in
new file mode 100644
index 0000000..20d8c5c
--- /dev/null
+++ b/ext/Makefile.in
@@ -0,0 +1,40 @@
+2SHELL = /bin/sh
+
+#### Start of system configuration section. ####
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+CC = @CC@
+
+CFLAGS = -I.. @CCDLFLAGS@ @CFLAGS@
+LIBS = @LIBS@
+EXT = @EXT@
+
+prefix = @prefix@
+binprefix =
+exec_prefix = @exec_prefix@
+bindir = $(exec_prefix)/bin
+
+#### End of system configuration section. ####
+
+.SUFFIXES: .so $(SUFFIXES)
+
+OBJS = dbm.$(EXT) \
+ socket.$(EXT)
+
+all: $(OBJS)
+
+clean:; @rm -f *.o *.so
+
+realclean:; @rm -f *.o *.so
+ @rm -f core ruby *~ Makefile
+
+.o.so:
+ ld -o $*.so $*.o
+
+# Prevent GNU make v3 from overflowing arg limit on SysV.
+.NOEXPORT:
+###
+dbm.o: dbm.c ../ruby.h ../config.h ../defines.h
+socket.o: socket.c ../ruby.h ../config.h ../defines.h ../io.h
diff --git a/ext/dbm.c b/ext/dbm.c
new file mode 100644
index 0000000..f3e8295
--- /dev/null
+++ b/ext/dbm.c
@@ -0,0 +1,441 @@
+/************************************************
+
+ dbm.c -
+
+ $Author: matz $
+ $Date: 1995/01/10 10:42:24 $
+ created at: Mon Jan 24 15:59:52 JST 1994
+
+ Copyright (C) 1995 Yukihiro Matsumoto
+
+************************************************/
+
+#include "ruby.h"
+
+#ifdef USE_DBM
+
+#include <ndbm.h>
+#include <fcntl.h>
+#include <errno.h>
+
+VALUE C_DBM;
+static ID id_dbm;
+
+extern VALUE M_Enumerable;
+
+static void
+closeddbm()
+{
+ Fail("closed DBM file");
+}
+
+#define GetDBM(obj, dbmp) {\
+ DBM **_dbm;\
+ Get_Data_Struct(obj, id_dbm, DBM*, _dbm);\
+ dbmp = *_dbm;\
+ if (dbmp == Qnil) closeddbm();\
+}
+
+static void
+free_dbm(dbmp)
+ DBM **dbmp;
+{
+ if (*dbmp) dbm_close(*dbmp);
+}
+
+#define MakeDBM(obj, dp) {\
+ DBM **_dbm;\
+ if (!id_dbm) id_dbm = rb_intern("dbm");\
+ Make_Data_Struct(obj,id_dbm,DBM*,Qnil,free_dbm,_dbm);\
+ *_dbm=dp;\
+}
+
+static VALUE
+Sdbm_open(argc, argv, class)
+ int argc;
+ VALUE *argv;
+ VALUE class;
+{
+ VALUE file, vmode;
+ DBM *dbm, **dbm2;
+ int mode;
+ VALUE obj;
+
+ if (rb_scan_args(argc, argv, "11", &file, &vmode) == 1) {
+ mode = 0666; /* default value */
+ }
+ else if (NIL_P(vmode)) {
+ mode = -1; /* return nil if DB not exist */
+ }
+ else {
+ mode = NUM2INT(vmode);
+ }
+ Check_Type(file, T_STRING);
+
+ dbm = Qnil;
+ if (mode >= 0)
+ dbm = dbm_open(RSTRING(file)->ptr, O_RDWR|O_CREAT, mode);
+ if (!dbm)
+ dbm = dbm_open(RSTRING(file)->ptr, O_RDWR, mode);
+ if (!dbm)
+ dbm = dbm_open(RSTRING(file)->ptr, O_RDONLY, mode);
+
+ if (!dbm) {
+ if (mode == -1) return Qnil;
+ rb_sys_fail(RSTRING(file)->ptr);
+ }
+
+ obj = obj_alloc(class);
+ MakeDBM(obj, dbm);
+
+ return obj;
+}
+
+static VALUE
+Fdbm_close(obj)
+ VALUE obj;
+{
+ DBM **dbmp;
+
+ Get_Data_Struct(obj, id_dbm, DBM*, dbmp);
+ if (*dbmp == Qnil) Fail("already closed DBM file");
+ dbm_close(*dbmp);
+ *dbmp = Qnil;
+
+ return Qnil;
+}
+
+static VALUE
+Fdbm_fetch(obj, keystr)
+ VALUE obj, keystr;
+{
+ datum key, value;
+ DBM *dbm;
+
+ Check_Type(keystr, T_STRING);
+ key.dptr = RSTRING(keystr)->ptr;
+ key.dsize = RSTRING(keystr)->len;
+
+ GetDBM(obj, dbm);
+ value = dbm_fetch(dbm, key);
+ if (value.dptr == Qnil) {
+ return Qnil;
+ }
+ return str_new(value.dptr, value.dsize);
+}
+
+static VALUE
+Fdbm_indexes(obj, args)
+ VALUE obj;
+ struct RArray *args;
+{
+ VALUE *p, *pend;
+ struct RArray *new;
+ int i = 0;
+
+ if (!args || args->len == 1 && TYPE(args->ptr) != T_ARRAY) {
+ args = (struct RArray*)rb_to_a(args->ptr[0]);
+ }
+
+ new = (struct RArray*)ary_new2(args->len);
+
+ p = args->ptr; pend = p + args->len;
+ while (p < pend) {
+ new->ptr[i++] = Fdbm_fetch(obj, *p++);
+ new->len = i;
+ }
+ return (VALUE)new;
+}
+
+static VALUE
+Fdbm_delete(obj, keystr)
+ VALUE obj, keystr;
+{
+ datum key;
+ DBM *dbm;
+
+ Check_Type(keystr, T_STRING);
+ key.dptr = RSTRING(keystr)->ptr;
+ key.dsize = RSTRING(keystr)->len;
+
+ GetDBM(obj, dbm);
+ if (dbm_delete(dbm, key)) {
+ Fail("dbm_delete failed");
+ }
+ return obj;
+}
+
+static VALUE
+Fdbm_shift(obj)
+ VALUE obj;
+{
+ datum key, val;
+ DBM *dbm;
+ VALUE keystr, valstr;
+
+ GetDBM(obj, dbm);
+
+ key = dbm_firstkey(dbm);
+ if (!key.dptr) return Qnil;
+ val = dbm_fetch(dbm, key);
+ dbm_delete(dbm, key);
+
+ keystr = str_new(key.dptr, key.dsize);
+ valstr = str_new(val.dptr, val.dsize);
+ return assoc_new(keystr, valstr);
+}
+
+static VALUE
+Fdbm_delete_if(obj)
+ VALUE obj;
+{
+ datum key, val;
+ DBM *dbm;
+ VALUE keystr, valstr;
+
+ GetDBM(obj, dbm);
+ for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
+ val = dbm_fetch(dbm, key);
+ keystr = str_new(key.dptr, key.dsize);
+ valstr = str_new(val.dptr, val.dsize);
+ if (rb_yield(assoc_new(keystr, valstr))
+ && dbm_delete(dbm, key)) {
+ Fail("dbm_delete failed");
+ }
+ }
+ return obj;
+}
+
+static VALUE
+Fdbm_clear(obj)
+ VALUE obj;
+{
+ datum key;
+ DBM *dbm;
+
+ GetDBM(obj, dbm);
+ for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
+ if (dbm_delete(dbm, key)) {
+ Fail("dbm_delete failed");
+ }
+ }
+ return obj;
+}
+
+static VALUE
+Fdbm_store(obj, keystr, valstr)
+ VALUE obj, keystr, valstr;
+{
+ datum key, val;
+ DBM *dbm;
+
+ if (valstr == Qnil) {
+ Fdbm_delete(obj, keystr);
+ return Qnil;
+ }
+
+ Check_Type(keystr, T_STRING);
+ key.dptr = RSTRING(keystr)->ptr;
+ key.dsize = RSTRING(keystr)->len;
+ Check_Type(valstr, T_STRING);
+ val.dptr = RSTRING(valstr)->ptr;
+ val.dsize = RSTRING(valstr)->len;
+
+ GetDBM(obj, dbm);
+ if (dbm_store(dbm, key, val, DBM_REPLACE)) {
+ dbm_clearerr(dbm);
+ if (errno == EPERM) rb_sys_fail(Qnil);
+ Fail("dbm_store failed");
+ }
+ return valstr;
+}
+
+static VALUE
+Fdbm_length(obj)
+ VALUE obj;
+{
+ datum key;
+ DBM *dbm;
+ int i = 0;
+
+ GetDBM(obj, dbm);
+ for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
+ i++;
+ }
+ return INT2FIX(i);
+}
+
+static VALUE
+Fdbm_each_value(obj)
+ VALUE obj;
+{
+ datum key, val;
+ DBM *dbm;
+
+ GetDBM(obj, dbm);
+ for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
+ val = dbm_fetch(dbm, key);
+ rb_yield(str_new(val.dptr, val.dsize));
+ }
+ return obj;
+}
+
+static VALUE
+Fdbm_each_key(obj)
+ VALUE obj;
+{
+ datum key;
+ DBM *dbm;
+
+ GetDBM(obj, dbm);
+ for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
+ rb_yield(str_new(key.dptr, key.dsize));
+ }
+ return obj;
+}
+
+static VALUE
+Fdbm_each_pair(obj)
+ VALUE obj;
+{
+ datum key, val;
+ DBM *dbm;
+ VALUE keystr, valstr;
+
+ GetDBM(obj, dbm);
+
+ for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
+ val = dbm_fetch(dbm, key);
+ keystr = str_new(key.dptr, key.dsize);
+ valstr = str_new(val.dptr, val.dsize);
+ rb_yield(assoc_new(keystr, valstr));
+ }
+
+ return obj;
+}
+
+static VALUE
+Fdbm_keys(obj)
+ VALUE obj;
+{
+ datum key;
+ DBM *dbm;
+ VALUE ary;
+
+ ary = ary_new();
+ GetDBM(obj, dbm);
+ for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
+ ary_push(ary, str_new(key.dptr, key.dsize));
+ }
+
+ return ary;
+}
+
+static VALUE
+Fdbm_values(obj)
+ VALUE obj;
+{
+ datum key, val;
+ DBM *dbm;
+ VALUE ary;
+
+ ary = ary_new();
+ GetDBM(obj, dbm);
+ for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
+ val = dbm_fetch(dbm, key);
+ ary_push(ary, str_new(val.dptr, val.dsize));
+ }
+
+ return ary;
+}
+
+static VALUE
+Fdbm_has_key(obj, keystr)
+ VALUE obj, keystr;
+{
+ datum key, val;
+ DBM *dbm;
+
+ Check_Type(keystr, T_STRING);
+ key.dptr = RSTRING(keystr)->ptr;
+ key.dsize = RSTRING(keystr)->len;
+
+ GetDBM(obj, dbm);
+ val = dbm_fetch(dbm, key);
+ if (val.dptr) return TRUE;
+ return FALSE;
+}
+
+static VALUE
+Fdbm_has_value(obj, valstr)
+ VALUE obj, valstr;
+{
+ datum key, val;
+ DBM *dbm;
+
+ Check_Type(valstr, T_STRING);
+ val.dptr = RSTRING(valstr)->ptr;
+ val.dsize = RSTRING(valstr)->len;
+
+ GetDBM(obj, dbm);
+ for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
+ val = dbm_fetch(dbm, key);
+ if (val.dsize == RSTRING(valstr)->len &&
+ memcmp(val.dptr, RSTRING(valstr)->ptr, val.dsize) == 0)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static VALUE
+Fdbm_to_a(obj)
+ VALUE obj;
+{
+ datum key, val;
+ DBM *dbm;
+ VALUE ary;
+
+ GetDBM(obj, dbm);
+
+ ary = ary_new();
+ for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
+ val = dbm_fetch(dbm, key);
+ ary_push(ary, assoc_new(str_new(key.dptr, key.dsize),
+ str_new(val.dptr, val.dsize)));
+ }
+
+ return ary;
+}
+
+Init_dbm()
+{
+#ifdef HAVE_LIBDBM
+ dln_load_lib("libdbm.a");
+#endif
+ C_DBM = rb_define_class("DBM", C_Object);
+ rb_include_module(C_DBM, M_Enumerable);
+
+ rb_define_single_method(C_DBM, "open", Sdbm_open, -1);
+ rb_define_method(C_DBM, "close", Fdbm_close, 0);
+ rb_define_method(C_DBM, "[]", Fdbm_fetch, 1);
+ rb_define_method(C_DBM, "[]=", Fdbm_store, 2);
+ rb_define_method(C_DBM, "indexes", Fdbm_indexes, -2);
+ rb_define_method(C_DBM, "length", Fdbm_length, 0);
+ rb_define_alias(C_DBM, "size", "length");
+ rb_define_method(C_DBM, "each", Fdbm_each_pair, 0);
+ rb_define_method(C_DBM, "each_value", Fdbm_each_value, 0);
+ rb_define_method(C_DBM, "each_key", Fdbm_each_key, 0);
+ rb_define_method(C_DBM, "each_pair", Fdbm_each_pair, 0);
+ rb_define_method(C_DBM, "keys", Fdbm_keys, 0);
+ rb_define_method(C_DBM, "values", Fdbm_values, 0);
+ rb_define_method(C_DBM, "shift", Fdbm_shift, 1);
+ rb_define_method(C_DBM, "delete", Fdbm_delete, 1);
+ rb_define_method(C_DBM, "delete_if", Fdbm_delete_if, 0);
+ rb_define_method(C_DBM, "clear", Fdbm_clear, 0);
+ rb_define_method(C_DBM, "includes", Fdbm_has_key, 1);
+ rb_define_method(C_DBM, "has_key", Fdbm_has_key, 1);
+ rb_define_method(C_DBM, "has_value", Fdbm_has_value, 1);
+
+ rb_define_method(C_DBM, "to_a", Fdbm_to_a, 0);
+}
+#endif /* USE_DBM */
diff --git a/ext/dbm.doc b/ext/dbm.doc
new file mode 100644
index 0000000..48c91a9
--- /dev/null
+++ b/ext/dbm.doc
@@ -0,0 +1,107 @@
+.\" dbm.doc - -*- Indented-Text -*- created at: Thu Mar 23 20:28:31 JST 1995
+
+** DBM(饹)
+
+NDBMե򥢥륯饹ǡȤʸǤʤФ
+ʤȤ¤ȡǡե¸ȤƤ
+Dict饹Ʊͤ˰ȤǤ롥NDBMƤʤƥǤ
+Υ饹ʤ
+
+SuperClass: Object
+
+Included Modules: Enumerable
+
+Methods:
+
+ self [key]
+
+ key򥭡Ȥ֤ͤ
+
+ self [key]= value
+
+ key򥭡ȤơvalueǼ롥valueȤnilꤹȡ
+ keyФܤκȤʤ롥
+
+ clear
+
+ DBMեȤˤ롥
+
+ close
+
+ DBMե򥯥롥ʸ㳰ȯ롥
+
+ delete(key)
+
+ key򥭡ȤȤ롥
+
+ delete_if
+
+ Ǥ륤ƥ졼key::valueȤڥͿơ֥
+ ɾͤλܤ롥
+
+ each
+ each_pair
+
+ key::valueʤڥͿ륤ƥ졼
+
+ each_key
+
+ ƤkeyФƷ֤ƥ졼
+
+ each_value
+
+ ƤvalueФƷ֤ƥ졼
+
+ has_key(key)
+ includes(key)
+
+ keyǡ١¸ߤ֤
+
+ has_value(value)
+
+ valueͤȤȤǡ١¸ߤ
+ ֤
+
+ indexes(ary)
+ indexes(key-1, ..., key-n)
+
+ 1ܤηǤʸȤƼơǤ򥭡
+ ȤǤޤ֤2ܤηǤϳưͤ򥭡
+ Ǥޤ֤.
+
+ keys
+
+ ǡ١¸ߤ륭Ƥޤ֤
+
+ length
+ size
+
+ ǡ١Ǥο֤(:ߤμ¸Ǥǿ
+ 뤿˥ǡ١Τǡ빽Ȥ⤤
+ ĤƻȤ.)
+
+ shift
+
+ ǡ١ǤļФ(ǡ١)
+ key::valueȤڥ֤
+
+ to_a
+
+ ǡ١key-valueڥǤȤ֤
+
+ values
+
+ ǡ١¸ߤƤޤ֤
+
+Single Methods:
+
+ open(dbname[, mode])
+
+ dbnameǻꤷǡ١⡼ɤmodeꤷƥץ
+ 롥modeξάͤ0666Ǥ롥modeȤnilꤹȥǡ
+ ١¸ߤʤˤϿ˥ץ󤻤nil֤
+
+-------------------------------------------------------
+Local variables:
+fill-column: 70
+end:
diff --git a/ext/socket.c b/ext/socket.c
new file mode 100644
index 0000000..ec99234
--- /dev/null
+++ b/ext/socket.c
@@ -0,0 +1,761 @@
+/************************************************
+
+ socket.c -
+
+ $Author: matz $
+ $Date: 1995/01/10 10:42:55 $
+ created at: Thu Mar 31 12:21:29 JST 1994
+
+************************************************/
+
+#include "ruby.h"
+#ifdef HAVE_SOCKET
+#include "io.h"
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <errno.h>
+#include <sys/un.h>
+
+extern VALUE C_IO;
+VALUE C_BasicSocket;
+VALUE C_TCPsocket;
+VALUE C_TCPserver;
+VALUE C_UNIXsocket;
+VALUE C_UNIXserver;
+VALUE C_Socket;
+
+FILE *rb_fdopen();
+char *strdup();
+
+static VALUE
+sock_new(class, fd)
+ VALUE class;
+ int fd;
+{
+ VALUE sock = obj_alloc(class);
+ OpenFile *fp;
+
+ MakeOpenFile(sock, fp);
+ fp->f = rb_fdopen(fd, "r");
+ setbuf(fp->f, NULL);
+ fp->f2 = rb_fdopen(fd, "w");
+ fp->mode = FMODE_READWRITE|FMODE_SYNC;
+
+ return sock;
+}
+
+static VALUE
+Fbsock_shutdown(argc, argv, sock)
+ int argc;
+ VALUE *argv;
+ VALUE sock;
+{
+ VALUE howto;
+ int how;
+ OpenFile *fptr;
+
+ rb_scan_args(argc, argv, "01", &howto);
+ if (howto == Qnil)
+ how = 2;
+ else {
+ how = NUM2INT(howto);
+ if (how < 0 && how > 2) how = 2;
+ }
+ GetOpenFile(sock, fptr);
+ if (shutdown(fileno(fptr->f), how) == -1)
+ rb_sys_fail(Qnil);
+
+ return INT2FIX(0);
+}
+
+static VALUE
+Fbsock_setopt(sock, lev, optname, val)
+ VALUE sock, lev, optname;
+ struct RString *val;
+{
+ int level, option;
+ OpenFile *fptr;
+
+ level = NUM2INT(lev);
+ option = NUM2INT(optname);
+ Check_Type(val, T_STRING);
+
+ GetOpenFile(sock, fptr);
+ if (setsockopt(fileno(fptr->f), level, option, val->ptr, val->len) < 0)
+ rb_sys_fail(fptr->path);
+
+ return INT2FIX(0);
+}
+
+static VALUE
+Fbsock_getopt(sock, lev, optname)
+ VALUE sock, lev, optname;
+{
+ int level, option, len;
+ struct RString *val;
+ OpenFile *fptr;
+
+ level = NUM2INT(lev);
+ option = NUM2INT(optname);
+ len = 256;
+ val = (struct RString*)str_new(0, len);
+ Check_Type(val, T_STRING);
+
+ GetOpenFile(sock, fptr);
+ if (getsockopt(fileno(fptr->f), level, option, val->ptr, &len) < 0)
+ rb_sys_fail(fptr->path);
+ val->len = len;
+ return (VALUE)val;
+}
+
+static VALUE
+Fbsock_getsockname(sock)
+ VALUE sock;
+{
+ char buf[1024];
+ int len = sizeof buf;
+ OpenFile *fptr;
+
+ GetOpenFile(sock, fptr);
+ if (getsockname(fileno(fptr->f), (struct sockaddr*)buf, &len) < 0)
+ rb_sys_fail("getsockname(2)");
+ return str_new(buf, len);
+}
+
+static VALUE
+Fbsock_getpeername(sock)
+ VALUE sock;
+{
+ char buf[1024];
+ int len = sizeof buf;
+ OpenFile *fptr;
+
+ GetOpenFile(sock, fptr);
+ if (getpeername(fileno(fptr->f), (struct sockaddr*)buf, &len) < 0)
+ rb_sys_fail("getpeername(2)");
+ return str_new(buf, len);
+}
+
+static VALUE
+open_inet(class, h, serv, server)
+ VALUE class, h, serv;
+ int server;
+{
+ char *host;
+ struct hostent *hostent, _hostent;
+ struct servent *servent, _servent;
+ struct protoent *protoent;
+ struct sockaddr_in sockaddr;
+ int fd, status;
+ int hostaddr, hostaddrPtr[2];
+ int servport;
+ char *syscall;
+ VALUE sock;
+
+ if (h) {
+ Check_Type(h, T_STRING);
+ host = RSTRING(h)->ptr;
+ hostent = gethostbyname(host);
+ if (hostent == NULL) {
+ hostaddr = inet_addr(host);
+ if (hostaddr == -1) {
+ if (server && !strlen(host))
+ hostaddr = INADDR_ANY;
+ else
+ rb_sys_fail(host);
+ }
+ _hostent.h_addr_list = (char **)hostaddrPtr;
+ _hostent.h_addr_list[0] = (char *)&hostaddr;
+ _hostent.h_addr_list[1] = NULL;
+ _hostent.h_length = sizeof(hostaddr);
+ _hostent.h_addrtype = AF_INET;
+ hostent = &_hostent;
+ }
+ }
+ servent = NULL;
+ if (FIXNUM_P(serv)) {
+ servport = FIX2UINT(serv);
+ goto setup_servent;
+ }
+ Check_Type(serv, T_STRING);
+ servent = getservbyname(RSTRING(serv)->ptr, "tcp");
+ if (servent == NULL) {
+ servport = strtoul(RSTRING(serv)->ptr, Qnil, 0);
+ if (servport == -1) Fail("no such servce %s", RSTRING(serv)->ptr);
+ setup_servent:
+ _servent.s_port = servport;
+ _servent.s_proto = "tcp";
+ servent = &_servent;
+ }
+ protoent = getprotobyname(servent->s_proto);
+ if (protoent == NULL) Fail("no such proto %s", servent->s_proto);
+
+ fd = socket(PF_INET, SOCK_STREAM, protoent->p_proto);
+
+ sockaddr.sin_family = AF_INET;
+ if (h == Qnil) {
+ sockaddr.sin_addr.s_addr = INADDR_ANY;
+ }
+ else {
+ memcpy((char *)&(sockaddr.sin_addr.s_addr),
+ (char *) hostent->h_addr_list[0],
+ (size_t) hostent->h_length);
+ }
+ sockaddr.sin_port = servent->s_port;
+
+ if (server) {
+ status = bind(fd, (struct sockaddr*)&sockaddr, sizeof(sockaddr));
+ syscall = "bind(2)";
+ }
+ else {
+ status = connect(fd, (struct sockaddr*)&sockaddr, sizeof(sockaddr));
+ syscall = "connect(2)";
+ }
+
+ if (status < 0) {
+ close (fd);
+ rb_sys_fail(syscall);
+ }
+ if (server) listen(fd, 5);
+
+ /* create new instance */
+ sock = sock_new(class, fd);
+
+ return sock;
+}
+
+static VALUE
+Stcp_sock_open(class, host, serv)
+ VALUE class, host, serv;
+{
+ Check_Type(host, T_STRING);
+ return open_inet(class, host, serv, 0);
+}
+
+static VALUE
+Stcp_svr_open(argc, argv, class)
+ int argc;
+ VALUE *argv;
+ VALUE class;
+{
+ VALUE arg1, arg2;
+
+ if (rb_scan_args(argc, argv, "11", &arg1, &arg2) == 2)
+ return open_inet(class, arg1, arg2, 1);
+ else
+ return open_inet(class, Qnil, arg1, 1);
+}
+
+static VALUE
+sock_accept(class, fd, sockaddr, len)
+ VALUE class;
+ int fd;
+ struct sockaddr *sockaddr;
+ int *len;
+{
+ int fd2;
+
+ retry:
+ fd2 = accept(fd, sockaddr, len);
+ if (fd2 < 0) {
+ if (errno == EINTR) goto retry;
+ rb_sys_fail(Qnil);
+ }
+ return sock_new(class, fd2);
+}
+
+static VALUE
+Ftcp_accept(sock)
+ VALUE sock;
+{
+ OpenFile *fptr;
+ struct sockaddr_in from;
+ int fromlen;
+
+ GetOpenFile(sock, fptr);
+ fromlen = sizeof(struct sockaddr_in);
+ return sock_accept(C_TCPsocket, fileno(fptr->f),
+ (struct sockaddr*)&from, &fromlen);
+}
+
+static VALUE
+open_unix(class, path, server)
+ VALUE class;
+ struct RString *path;
+ int server;
+{
+ struct sockaddr_un sockaddr;
+ int fd, status;
+ char *syscall;
+ VALUE sock;
+ OpenFile *fptr;
+
+ Check_Type(path, T_STRING);
+ fd = socket(PF_UNIX, SOCK_STREAM, 0);
+ if (fd < 0) rb_sys_fail("socket(2)");
+
+ sockaddr.sun_family = AF_UNIX;
+ strncpy(sockaddr.sun_path, path->ptr, sizeof(sockaddr.sun_path)-1);
+ sockaddr.sun_path[sizeof(sockaddr.sun_path)-1] = '\0';
+
+ if (server) {
+ status = bind(fd, (struct sockaddr*)&sockaddr, sizeof(sockaddr));
+ syscall = "bind(2)";
+ }
+ else {
+ status = connect(fd, (struct sockaddr*)&sockaddr, sizeof(sockaddr));
+ syscall = "connect(2)";
+ }
+
+ if (status < 0) {
+ close (fd);
+ rb_sys_fail(syscall);
+ }
+
+ if (server) listen(fd, 5);
+
+ sock = sock_new(class, fd);
+ GetOpenFile(sock, fptr);
+ fptr->path = strdup(path->ptr);
+
+ return sock;
+}
+
+static VALUE
+tcp_addr(sockaddr)
+ struct sockaddr_in *sockaddr;
+{
+ VALUE family, port, addr;
+ VALUE ary;
+ struct hostent *hostent;
+
+ family = str_new2("AF_INET");
+ hostent = gethostbyaddr((char*)&sockaddr->sin_addr.s_addr,
+ sizeof(sockaddr->sin_addr),
+ AF_INET);
+ if (hostent) {
+ addr = str_new2(hostent->h_name);
+ }
+ else {
+ char buf[16];
+ char *a = (char*)&sockaddr->sin_addr;
+ sprintf(buf, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
+ addr = str_new2(buf);
+ }
+ port = INT2FIX(sockaddr->sin_port);
+ ary = ary_new3(3, family, port, addr);
+
+ return ary;
+}
+
+static VALUE
+Ftcp_addr(sock)
+ VALUE sock;
+{
+ OpenFile *fptr;
+ struct sockaddr_in addr;
+ int len = sizeof addr;
+
+ GetOpenFile(sock, fptr);
+
+ if (getsockname(fileno(fptr->f), (struct sockaddr*)&addr, &len) < 0)
+ rb_sys_fail("getsockname(2)");
+ return tcp_addr(&addr);
+}
+
+static VALUE
+Ftcp_peeraddr(sock)
+ VALUE sock;
+{
+ OpenFile *fptr;
+ struct sockaddr_in addr;
+ int len = sizeof addr;
+
+ GetOpenFile(sock, fptr);
+
+ if (getpeername(fileno(fptr->f), (struct sockaddr*)&addr, &len) < 0)
+ rb_sys_fail("getsockname(2)");
+ return tcp_addr(&addr);
+}
+
+static VALUE
+Sunix_sock_open(sock, path)
+ VALUE sock, path;
+{
+ return open_unix(sock, path, 0);
+}
+
+static VALUE
+Funix_path(sock)
+ VALUE sock;
+{
+ OpenFile *fptr;
+
+ GetOpenFile(sock, fptr);
+ if (fptr->path == Qnil) {
+ struct sockaddr_un addr;
+ int len = sizeof(addr);
+ if (getsockname(fileno(fptr->f), (struct sockaddr*)&addr, &len) < 0)
+ rb_sys_fail(Qnil);
+ fptr->path = strdup(addr.sun_path);
+ }
+ return str_new2(fptr->path);
+}
+
+static VALUE
+Sunix_svr_open(class, path)
+ VALUE class, path;
+{
+ return open_unix(class, path, 1);
+}
+
+static VALUE
+Funix_accept(sock)
+ VALUE sock;
+{
+ OpenFile *fptr;
+ struct sockaddr_un from;
+ int fromlen;
+
+ GetOpenFile(sock, fptr);
+ fromlen = sizeof(struct sockaddr_un);
+ return sock_accept(C_UNIXsocket, fileno(fptr->f),
+ (struct sockaddr*)&from, &fromlen);
+}
+
+static VALUE
+unix_addr(sockaddr)
+ struct sockaddr_un *sockaddr;
+{
+ return assoc_new(str_new2("AF_UNIX"),str_new2(sockaddr->sun_path));
+}
+
+static VALUE
+Funix_addr(sock)
+ VALUE sock;
+{
+ OpenFile *fptr;
+ struct sockaddr_un addr;
+ int len = sizeof addr;
+
+ GetOpenFile(sock, fptr);
+
+ if (getsockname(fileno(fptr->f), (struct sockaddr*)&addr, &len) < 0)
+ rb_sys_fail("getsockname(2)");
+ return unix_addr(&addr);
+}
+
+static VALUE
+Funix_peeraddr(sock)
+ VALUE sock;
+{
+ OpenFile *fptr;
+ struct sockaddr_un addr;
+ int len = sizeof addr;
+
+ GetOpenFile(sock, fptr);
+
+ if (getpeername(fileno(fptr->f), (struct sockaddr*)&addr, &len) < 0)
+ rb_sys_fail("getsockname(2)");
+ return unix_addr(&addr);
+}
+
+static void
+setup_domain_and_type(domain, dv, type, tv)
+ VALUE domain, type;
+ int *dv, *tv;
+{
+ char *ptr;
+
+ if (TYPE(domain) == T_STRING) {
+ ptr = RSTRING(domain)->ptr;
+ if (strcmp(ptr, "PF_UNIX") == 0)
+ *dv = PF_UNIX;
+ else if (strcmp(ptr, "PF_INET") == 0)
+ *dv = PF_INET;
+#ifdef PF_IMPLINK
+ else if (strcmp(ptr, "PF_IMPLINK") == 0)
+ *dv = PF_IMPLINK;
+#endif
+#ifdef PF_AX25
+ else if (strcmp(ptr, "PF_AX25") == 0)
+ *dv = PF_AX25;
+#endif
+#ifdef PF_IPX
+ else if (strcmp(ptr, "PF_IPX") == 0)
+ *dv = PF_IPX;
+#endif
+ else
+ Fail("Unknown socket domain %s", ptr);
+ }
+ else {
+ *dv = NUM2INT(domain);
+ }
+ if (TYPE(type) == T_STRING) {
+ ptr = RSTRING(type)->ptr;
+ if (strcmp(ptr, "SOCK_STREAM") == 0)
+ *tv = SOCK_STREAM;
+ else if (strcmp(ptr, "SOCK_DGRAM") == 0)
+ *tv = SOCK_DGRAM;
+#ifdef SOCK_RAW
+ else if (strcmp(ptr, "SOCK_RAW") == 0)
+ *tv = SOCK_RAW;
+#endif
+#ifdef SOCK_SEQPACKET
+ else if (strcmp(ptr, "SOCK_SEQPACKET") == 0)
+ *tv = SOCK_SEQPACKET;
+#endif
+#ifdef SOCK_RDM
+ else if (strcmp(ptr, "SOCK_RDM") == 0)
+ *tv = SOCK_RDM;
+#endif
+#ifdef SOCK_PACKET
+ else if (strcmp(ptr, "SOCK_PACKET") == 0)
+ *tv = SOCK_PACKET;
+#endif
+ else
+ Fail("Unknown socket type %s", ptr);
+ }
+ else {
+ *tv = NUM2INT(type);
+ }
+}
+
+static VALUE
+Ssock_open(class, domain, type, protocol)
+ VALUE class, domain, type, protocol;
+{
+ int fd;
+ int d, t;
+
+ setup_domain_and_type(domain, &d, type, &t);
+ fd = socket(d, t, NUM2INT(protocol));
+ if (fd < 0) rb_sys_fail("socke(2)");
+ return sock_new(class, fd);
+}
+
+static VALUE
+Ssock_for_fd(class, fd)
+ VALUE class, fd;
+{
+ return sock_new(class, NUM2INT(fd));
+}
+
+static VALUE
+Ssock_socketpair(class, domain, type, protocol)
+ VALUE class, domain, type, protocol;
+{
+ int fd;
+ int d, t, sp[2];
+
+ setup_domain_and_type(domain, &d, type, &t);
+ if (socketpair(d, t, NUM2INT(protocol), sp) < 0)
+ rb_sys_fail("socketpair(2)");
+
+ return assoc_new(sock_new(class, sp[0]), sock_new(class, sp[1]));
+}
+
+static VALUE
+Fsock_connect(sock, addr)
+ VALUE sock;
+ struct RString *addr;
+{
+ OpenFile *fptr;
+
+ Check_Type(addr, T_STRING);
+ str_modify(addr);
+
+ GetOpenFile(sock, fptr);
+ if (connect(fileno(fptr->f), (struct sockaddr*)addr->ptr, addr->len) < 0)
+ rb_sys_fail("connect(2)");
+
+ return INT2FIX(0);
+}
+
+static VALUE
+Fsock_bind(sock, addr)
+ VALUE sock;
+ struct RString *addr;
+{
+ OpenFile *fptr;
+
+ Check_Type(addr, T_STRING);
+ str_modify(addr);
+
+ GetOpenFile(sock, fptr);
+ if (bind(fileno(fptr->f), (struct sockaddr*)addr->ptr, addr->len) < 0)
+ rb_sys_fail("bind(2)");
+
+ return INT2FIX(0);
+}
+
+static VALUE
+Fsock_listen(sock, log)
+ VALUE sock, log;
+{
+ OpenFile *fptr;
+
+ GetOpenFile(sock, fptr);
+ if (listen(fileno(fptr->f), NUM2INT(log)) < 0)
+ rb_sys_fail("listen(2)");
+
+ return INT2FIX(0);
+}
+
+static VALUE
+Fsock_accept(sock)
+ VALUE sock;
+{
+ OpenFile *fptr;
+ VALUE addr, sock2;
+ char buf[1024];
+ int len = sizeof buf;
+
+ GetOpenFile(sock, fptr);
+ sock2 = sock_accept(C_Socket,fileno(fptr->f),(struct sockaddr*)buf,&len);
+
+ return assoc_new(sock2, str_new(buf, len));
+}
+
+static VALUE
+Fsock_send(argc, argv, sock)
+ int argc;
+ VALUE *argv;
+ VALUE sock;
+{
+ struct RString *msg, *to;
+ VALUE flags;
+ OpenFile *fptr;
+ FILE *f;
+ int fd, n;
+
+ rb_scan_args(argc, argv, "21", &msg, &flags, &to);
+
+ Check_Type(msg, T_STRING);
+
+ GetOpenFile(sock, fptr);
+ f = fptr->f2?fptr->f2:fptr->f;
+ fd = fileno(f);
+ if (to) {
+ Check_Type(to, T_STRING);
+ n = sendto(fd, msg->ptr, msg->len, NUM2INT(flags),
+ (struct sockaddr*)to->ptr, to->len);
+ }
+ else {
+ n = send(fd, msg->ptr, msg->len, NUM2INT(flags));
+ }
+ if (n < 0) {
+ rb_sys_fail("send(2)");
+ }
+ return INT2FIX(n);
+}
+
+static VALUE
+sock_recv(sock, argc, argv, from)
+ VALUE sock;
+ int argc;
+ VALUE *argv;
+ int from;
+{
+ OpenFile *fptr;
+ FILE f;
+ struct RString *str;
+ char buf[1024];
+ int fd, alen = sizeof buf;
+ VALUE len, flg;
+ int flags;
+
+ rb_scan_args(argc, argv, "11", &len, &flg);
+
+ if (flg == Qnil) flags = 0;
+ else flags = NUM2INT(flg);
+
+ str = (struct RString*)str_new(0, NUM2INT(len));
+
+ GetOpenFile(sock, fptr);
+ fd = fileno(fptr->f);
+ if ((str->len = recvfrom(fd, str->ptr, str->len, flags,
+ (struct sockaddr*)buf, &alen)) < 0) {
+ rb_sys_fail("recvfrom(2)");
+ }
+
+ if (from)
+ return assoc_new(str, str_new(buf, alen));
+ else
+ return (VALUE)str;
+}
+
+static VALUE
+Fsock_recv(argc, argv, sock)
+ int argc;
+ VALUE *argv;
+ VALUE sock;
+{
+ return sock_recv(sock, argc, argv, 0);
+}
+
+static VALUE
+Fsock_recvfrom(argc, argv, sock)
+ int argc;
+ VALUE *argv;
+ VALUE sock;
+{
+ return sock_recv(sock, argc, argv, 1);
+}
+
+Init_socket ()
+{
+#ifdef HAVE_LIBSOCKET
+ dln_load_lib("libsocket.a");
+#endif
+ C_BasicSocket = rb_define_class("BasicSocket", C_IO);
+ rb_undef_method(C_BasicSocket, "new");
+ rb_define_method(C_BasicSocket, "shutdown", Fbsock_shutdown, -1);
+ rb_define_method(C_BasicSocket, "setopt", Fbsock_setopt, 3);
+ rb_define_method(C_BasicSocket, "getopt", Fbsock_getopt, 2);
+ rb_define_method(C_BasicSocket, "getsockname", Fbsock_getsockname, 0);
+ rb_define_method(C_BasicSocket, "getpeername", Fbsock_getpeername, 0);
+
+ C_TCPsocket = rb_define_class("TCPsocket", C_BasicSocket);
+ rb_define_single_method(C_TCPsocket, "open", Stcp_sock_open, 2);
+ rb_define_single_method(C_TCPsocket, "new", Stcp_sock_open, 2);
+ rb_define_method(C_TCPsocket, "addr", Ftcp_addr, 0);
+ rb_define_method(C_TCPsocket, "peeraddr", Ftcp_peeraddr, 0);
+
+ C_TCPserver = rb_define_class("TCPserver", C_TCPsocket);
+ rb_define_single_method(C_TCPserver, "open", Stcp_svr_open, -1);
+ rb_define_single_method(C_TCPserver, "new", Stcp_svr_open, -1);
+ rb_define_method(C_TCPserver, "accept", Ftcp_accept, 0);
+
+ C_UNIXsocket = rb_define_class("UNIXsocket", C_BasicSocket);
+ rb_define_single_method(C_UNIXsocket, "open", Sunix_sock_open, 1);
+ rb_define_single_method(C_UNIXsocket, "new", Sunix_sock_open, 1);
+ rb_define_method(C_UNIXsocket, "path", Funix_path, 0);
+ rb_define_method(C_UNIXsocket, "addr", Funix_addr, 0);
+ rb_define_method(C_UNIXsocket, "peeraddr", Funix_peeraddr, 0);
+
+ C_UNIXserver = rb_define_class("UNIXserver", C_UNIXsocket);
+ rb_define_single_method(C_UNIXserver, "open", Sunix_svr_open, 1);
+ rb_define_single_method(C_UNIXserver, "new", Sunix_svr_open, 1);
+ rb_define_method(C_UNIXserver, "accept", Funix_accept, 0);
+
+ C_Socket = rb_define_class("Socket", C_BasicSocket);
+ rb_define_single_method(C_Socket, "open", Ssock_open, 3);
+ rb_define_single_method(C_Socket, "new", Ssock_open, 3);
+ rb_define_single_method(C_Socket, "for_fd", Ssock_for_fd, 1);
+
+ rb_define_method(C_Socket, "connect", Fsock_connect, 1);
+ rb_define_method(C_Socket, "bind", Fsock_bind, 1);
+ rb_define_method(C_Socket, "listen", Fsock_listen, 1);
+ rb_define_method(C_Socket, "accept", Fsock_accept, 0);
+
+ rb_define_method(C_Socket, "send", Fsock_send, -1);
+ rb_define_method(C_Socket, "recv", Fsock_recv, -1);
+ rb_define_method(C_Socket, "recvfrom", Fsock_recv, -1);
+
+ rb_define_single_method(C_Socket, "socketpair", Ssock_socketpair, 3);
+}
+#endif /* HAVE_SOCKET */
diff --git a/ext/socket.doc b/ext/socket.doc
new file mode 100644
index 0000000..aa5bfed
--- /dev/null
+++ b/ext/socket.doc
@@ -0,0 +1,227 @@
+.\" socket.doc - -*- Indented-Text -*- created at: Thu Mar 23 20:29:02 JST 1995
+
+** Socket(饹)
+
+SuperClass: BasicSocket
+
+åȤΤΤФ륷ƥॳ٥Υ󶡤륯饹
+PerlΥåȤФ륢Ʊ٥εǽ󶡤Ƥ롥Υ
+Ǥϥåȥɥ쥹pack줿ʸǡꤹ롥UDPåȤϤ
+Υ饹ȤäѤ롥
+
+Methods:
+
+ accept
+
+ ³դơ³Ф륽åȤȥɥ쥹
+ ڥ֤accept(2)򻲾ȡ
+
+ bind(addr)
+
+ bind(2)ƱƯ򤹤롥addrpack줿åȥɥ쥹¤
+ ΤǤ롥
+
+ connect(addr)
+
+ connect(2)ƱƯ򤹤롥addrpack줿åȥɥ쥹
+ ¤ΤǤ롥
+
+ listen(backlog)
+
+ listen(2)ƱƯ򤹤롥
+
+ recv(len[, flags])
+
+ åȤǡꡤʸȤ֤lenϼ
+ Ĺꤹ롥flagsˤĤƤrecv(2)򻲾ȡflagsΥ
+ եͤ0Ǥ롥
+
+ recvfrom(len[, flags])
+
+ recvƱͤ˥åȤǡ뤬ͤʸ
+ ꥽åȤΥɥ쥹ΥڥǤ롥ˤĤƤrecvƱ͡
+
+ send(mesg, flags[, to])
+
+ åȤ𤷤ƥǡ롥flags˴ؤƤsend(2)򻲾Ȥλ
+ connectƤʤåȤФƤǤtoꤹɬ
+ פ롥ºݤäǡĹ֤
+
+Single Methods:
+
+ open(domain, type, protocol)
+ new(domain, type, protocol)
+
+ åȤ롥domaintypeprotocolϥ󥯥롼
+ եƤͤǻꤹ롥domaintype˴ؤ
+ ϡʸǻǤ뤬٤Ƥ򥫥СƤݾڤϤʤ
+
+ socketpair(domain, type, protocol)
+
+ åȤΥڥ֤λ openƱǤ롥
+
+** BasicSocket(饹)
+
+åȤɽݥ饹Ūʥåϥ֥饹롥
+㤨Х󥿡ͥåȥɥᥤξTCPsocketѤ롥
+
+SuperClass: IO
+
+Methods:
+
+ getopt(level, optname)
+
+ åȤΥץ롥getsockopt(2)򻲾ȤΤȡ
+ ץƤޤʸ֤
+
+ getpeername
+
+ ³ΥåȤξ롥ѥå줿sockaddr¤
+ ٥˥פʸ֤롥getpeername(2)򻲾ȤΤȡ
+
+ getsockname
+
+ åȤξ롥ѥå줿sockaddr¤Τ٥˥
+ ʸ֤롥getsockname(2)򻲾ȤΤȡ
+
+ setopt(level, optname, optval)
+
+ åȤΥץꤹ롥setsockopt(2)򻲾ȤΤȡ
+
+ shutdown(how)
+
+ åȤΰʹߤ³λ롥how0Ǥʹߤμ
+ how1Ǥϡʹߤݤ롥how2λˤϡ
+ ʹߤȤ˵ݤ롥shutdown(2)򻲾ȡ
+
+** TCPserver(饹)
+
+TCP/IPȥ꡼෿³Υ¦ΥåȤΥ饹Υ饹ˤä
+ñ˥åȤѤФΥץߥ󥰤Ǥ롥㤨echo
+ФϰʲΤ褦ˤʤ롥
+
+ gs = TCPserver.open(4444)
+ socks = [gs]
+
+ while TRUE
+ nsock = select(socks);
+ if nsock == nil; continue end
+ for s in nsock[0]
+ if s == gs
+ socks.push(s.accept)
+ else
+ if s.eof
+ s.close
+ socks.delete(s)
+ else
+ str = s.gets
+ s.write(str)
+ end
+ end
+ end
+ end
+
+SuperClass: TCPsocket
+
+Methods:
+
+ accept
+
+ 饤Ȥ³׵դ³TCPsocketΥ
+ 󥹤֤
+
+Single Methods:
+
+ new([host, ]service)
+ open([host, ]service)
+
+ service/etc/services(ޤNIS)ϿƤ륵ӥ̾
+ ݡֹǻꤹ롥hostꤷϻꤷۥȤ
+ ³դ롥άƤΥۥȤ³׵
+ 롥
+
+** TCPsocket
+
+󥿡ͥåȥɥᥤΥȥ꡼෿åȤΥ饹̾IO饹
+֥饹ƱͤϤǤ롥Υ饹ˤäƥåȤѤ
+饤Ȥñ˵ҤǤ롥桼Ϥ򤽤ΤޤޥФž
+ϰʲΤ褦ˤʤ롥
+
+ s = TCPsocket("localhost", 4444)
+ while gets()
+ s.write($_)
+ print(s.read)
+ end
+
+SuperClass: BasicSocket
+
+Methods:
+
+ addr
+
+ åȤ³ɽ֤γǤ1
+ ʸ "AF_INET"2Ǥportֹ桤3ǤۥȤɽʸ
+ Ǥ롥
+
+ peeraddr
+
+ ³襽åȤξɽ֤γǤ
+ addr᥽åɤ֤ƱǤ롥
+
+Single Methods:
+
+ open(host, service)
+ new(host, service)
+
+ hostǻꤷۥȤserviceǻꤷݡȤ³
+ Ȥ֤hostϥۥ̾ޤϥ󥿡ͥåȥɥ쥹򼨤ʸ
+ service/etc/services(ޤNIS)ϿƤ륵
+ ̾ݡֹǤ롥
+
+** UNIXserver
+
+UNIXȥ꡼෿³Υ¦ΥåȤΥ饹
+
+SuperClass: UNIXsocket
+
+Methods:
+
+ accept
+
+ 饤Ȥ³׵դ³UNIXsocketΥ
+ 󥹤֤
+
+** UNIXsocket
+
+UNIXɥᥤΥȥ꡼෿åȤΥ饹̾IO饹Υ֥饹
+ƱͤϤǤ롥
+
+SuperClass: BasicSocket
+
+Methods:
+
+ addr
+
+ åȤ³ɽ֤γǤ1
+ ʸ "AF_UNIX"2ǤpathǤ롥
+
+ path
+
+ UNIXåȤΥѥ֤
+
+ peeraddr
+
+ ³襽åȤξɽ֤γǤ
+ addr᥽åɤ֤ƱǤ롥
+
+Single Methods:
+
+ open(path)
+ new(path)
+
+ pathǻꤷѥ̾Ѥ³åȤ֤
+
+-------------------------------------------------------
+Local variables:
+fill-column: 70
+end: