diff options
Diffstat (limited to 'ext')
-rw-r--r-- | ext/MANIFEST | 3 | ||||
-rw-r--r-- | ext/Setup | 7 | ||||
-rw-r--r-- | ext/dbm/MANIFEST | 5 | ||||
-rw-r--r-- | ext/dbm/dbm.c | 435 | ||||
-rw-r--r-- | ext/dbm/dbm.doc | 107 | ||||
-rw-r--r-- | ext/dbm/depend | 1 | ||||
-rw-r--r-- | ext/dbm/extconf.rb | 4 | ||||
-rw-r--r-- | ext/etc/MANIFEST | 5 | ||||
-rw-r--r-- | ext/etc/depend | 1 | ||||
-rw-r--r-- | ext/etc/etc.c | 260 | ||||
-rw-r--r-- | ext/etc/etc.doc | 73 | ||||
-rw-r--r-- | ext/etc/extconf.rb | 7 | ||||
-rw-r--r-- | ext/extmk.rb.in | 398 | ||||
-rw-r--r-- | ext/marshal/MANIFEST | 4 | ||||
-rw-r--r-- | ext/marshal/depend | 2 | ||||
-rw-r--r-- | ext/marshal/marshal.c | 565 | ||||
-rw-r--r-- | ext/marshal/marshal.doc | 45 | ||||
-rw-r--r-- | ext/socket/MANIFEST | 5 | ||||
-rw-r--r-- | ext/socket/depend | 1 | ||||
-rw-r--r-- | ext/socket/extconf.rb | 6 | ||||
-rw-r--r-- | ext/socket/socket.c | 785 | ||||
-rw-r--r-- | ext/socket/socket.doc | 227 | ||||
-rw-r--r-- | ext/tkutil/MANIFEST | 3 | ||||
-rw-r--r-- | ext/tkutil/extconf.rb | 11 | ||||
-rw-r--r-- | ext/tkutil/tkutil.c | 54 |
25 files changed, 2921 insertions, 93 deletions
diff --git a/ext/MANIFEST b/ext/MANIFEST deleted file mode 100644 index 9580b61544..0000000000 --- a/ext/MANIFEST +++ /dev/null @@ -1,3 +0,0 @@ -MANIFEST -extmk.rb.in - diff --git a/ext/Setup b/ext/Setup new file mode 100644 index 0000000000..93586ea0e6 --- /dev/null +++ b/ext/Setup @@ -0,0 +1,7 @@ +#option nodynamic + +#dbm +#etc +#marshal +#socket +tkutil diff --git a/ext/dbm/MANIFEST b/ext/dbm/MANIFEST new file mode 100644 index 0000000000..141b8dd601 --- /dev/null +++ b/ext/dbm/MANIFEST @@ -0,0 +1,5 @@ +MANIFEST +dbm.c +dbm.doc +depend +extconf.rb diff --git a/ext/dbm/dbm.c b/ext/dbm/dbm.c new file mode 100644 index 0000000000..dbdd99c0ca --- /dev/null +++ b/ext/dbm/dbm.c @@ -0,0 +1,435 @@ +/************************************************ + + 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" + +#include <ndbm.h> +#include <fcntl.h> +#include <errno.h> + +VALUE cDBM; +static ID id_dbm; + +extern VALUE mEnumerable; + +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 +fdbm_s_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() +{ + cDBM = rb_define_class("DBM", cObject); + rb_include_module(cDBM, mEnumerable); + + rb_define_singleton_method(cDBM, "open", fdbm_s_open, -1); + rb_define_method(cDBM, "close", fdbm_close, 0); + rb_define_method(cDBM, "[]", fdbm_fetch, 1); + rb_define_method(cDBM, "[]=", fdbm_store, 2); + rb_define_method(cDBM, "indexes", fdbm_indexes, -2); + rb_define_method(cDBM, "length", fdbm_length, 0); + rb_define_alias(cDBM, "size", "length"); + rb_define_method(cDBM, "each", fdbm_each_pair, 0); + rb_define_method(cDBM, "each_value", fdbm_each_value, 0); + rb_define_method(cDBM, "each_key", fdbm_each_key, 0); + rb_define_method(cDBM, "each_pair", fdbm_each_pair, 0); + rb_define_method(cDBM, "keys", fdbm_keys, 0); + rb_define_method(cDBM, "values", fdbm_values, 0); + rb_define_method(cDBM, "shift", fdbm_shift, 1); + rb_define_method(cDBM, "delete", fdbm_delete, 1); + rb_define_method(cDBM, "delete_if", fdbm_delete_if, 0); + rb_define_method(cDBM, "clear", fdbm_clear, 0); + rb_define_method(cDBM, "includes", fdbm_has_key, 1); + rb_define_method(cDBM, "has_key", fdbm_has_key, 1); + rb_define_method(cDBM, "has_value", fdbm_has_value, 1); + + rb_define_method(cDBM, "to_a", fdbm_to_a, 0); +} diff --git a/ext/dbm/dbm.doc b/ext/dbm/dbm.doc new file mode 100644 index 0000000000..45f174b7aa --- /dev/null +++ b/ext/dbm/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/dbm/depend b/ext/dbm/depend new file mode 100644 index 0000000000..40139962a7 --- /dev/null +++ b/ext/dbm/depend @@ -0,0 +1 @@ +dbm.o: dbm.c ../../ruby.h ../../config.h ../../defines.h diff --git a/ext/dbm/extconf.rb b/ext/dbm/extconf.rb new file mode 100644 index 0000000000..5105cd662f --- /dev/null +++ b/ext/dbm/extconf.rb @@ -0,0 +1,4 @@ +have_library("dbm", "dbm_open") +if have_func("dbm_open") + create_makefile("dbm") +end diff --git a/ext/etc/MANIFEST b/ext/etc/MANIFEST new file mode 100644 index 0000000000..a0f521b386 --- /dev/null +++ b/ext/etc/MANIFEST @@ -0,0 +1,5 @@ +MANIFEST +etc.c +etc.doc +depend +extconf.rb diff --git a/ext/etc/depend b/ext/etc/depend new file mode 100644 index 0000000000..5c95ef117a --- /dev/null +++ b/ext/etc/depend @@ -0,0 +1 @@ +etc.o : etc.c ../../ruby.h ../../config.h ../../defines.h diff --git a/ext/etc/etc.c b/ext/etc/etc.c new file mode 100644 index 0000000000..e4e4098f8a --- /dev/null +++ b/ext/etc/etc.c @@ -0,0 +1,260 @@ +/************************************************ + + etc.c - + + $Author: matz $ + $Date: 1995/01/10 10:42:32 $ + created at: Tue Mar 22 18:39:19 JST 1994 + +************************************************/ + +#include "ruby.h" + +#ifdef HAVE_GETPWENT +#include <pwd.h> +#endif + +#ifdef HAVE_GETGRENT +#include <grp.h> +#endif + +static VALUE sPasswd, sGroup; + +static VALUE +etc_getlogin(obj) + VALUE obj; +{ +#ifdef HAVE_GETLOGIN + char *getlogin(); + char *login = getlogin(); +#else + char *getenv(); + char *login = getenv("USER"); +#endif + + if (login) + return str_new2(login); + return Qnil; +} + +#ifdef HAVE_GETPWENT +static VALUE +setup_passwd(pwd) + struct passwd *pwd; +{ + if (pwd == Qnil) rb_sys_fail("/etc/passwd"); + return struct_new(sPasswd, + str_new2(pwd->pw_name), + str_new2(pwd->pw_passwd), + INT2FIX(pwd->pw_uid), + INT2FIX(pwd->pw_gid), + str_new2(pwd->pw_gecos), + str_new2(pwd->pw_dir), + str_new2(pwd->pw_shell), +#ifdef PW_CHANGE + INT2FIX(pwd->pw_change), +#endif +#ifdef PW_QUOTA + INT2FIX(pwd->pw_quota), +#endif +#ifdef PW_AGE + INT2FIX(pwd->pw_age), +#endif +#ifdef PW_CLASS + str_new2(pwd->pw_class), +#endif +#ifdef PW_COMMENT + str_new2(pwd->pw_comment), +#endif +#ifdef PW_EXPIRE + INT2FIX(pwd->pw_expire), +#endif + Qnil); +} +#endif + +static VALUE +etc_getpwuid(argc, argv, obj) + int argc; + VALUE *argv; + VALUE obj; +{ +#ifdef HAVE_GETPWENT + VALUE id; + int uid; + struct passwd *pwd; + + if (rb_scan_args(argc, argv, "01", &id) == 1) { + uid = NUM2INT(id); + } + else { + uid = getuid(); + } + pwd = getpwuid(uid); + if (pwd == Qnil) Fail("can't find user for %d", uid); + return setup_passwd(pwd); +#else + return Qnil; +#endif +} + +static VALUE +etc_getpwnam(obj, nam) + VALUE obj, nam; +{ +#ifdef HAVE_GETPWENT + struct passwd *pwd; + + Check_Type(nam, T_STRING); + pwd = getpwnam(RSTRING(nam)->ptr); + if (pwd == Qnil) Fail("can't find user for %s", RSTRING(nam)->ptr); + return setup_passwd(pwd); +#else + return Qnil; +#endif +} + +static VALUE +etc_passwd(obj) + VALUE obj; +{ +#ifdef HAVE_GETPWENT + struct passwd *pw; + + if (iterator_p()) { + setpwent(); + while (pw = getpwent()) { + rb_yield(setup_passwd(pw)); + } + endpwent(); + return obj; + } + pw = getpwent(); + if (pw == Qnil) Fail("can't fetch next -- /etc/passwd"); + return setup_passwd(pw); +#else + return Qnil; +#endif +} + +#ifdef HAVE_GETGRENT +static VALUE +setup_group(grp) + struct group *grp; +{ + VALUE mem; + char **tbl; + + mem = ary_new(); + tbl = grp->gr_mem; + while (*tbl) { + ary_push(mem, str_new2(*tbl)); + tbl++; + } + return struct_new(sGroup, + str_new2(grp->gr_name), + str_new2(grp->gr_passwd), + INT2FIX(grp->gr_gid), + mem, + Qnil); +} +#endif + +static VALUE +etc_getgrgid(obj, id) + VALUE obj, id; +{ +#ifdef HAVE_GETGRENT + int gid; + struct group *grp; + + gid = NUM2INT(id); + grp = getgrgid(gid); + if (grp == Qnil) Fail("can't find group for %d", gid); + return setup_group(grp); +#else + return Qnil; +#endif +} + +static VALUE +etc_getgrnam(obj, nam) + VALUE obj, nam; +{ +#ifdef HAVE_GETGRENT + struct group *grp; + + Check_Type(nam, T_STRING); + grp = getgrnam(RSTRING(nam)->ptr); + if (grp == Qnil) Fail("can't find group for %s", RSTRING(nam)->ptr); + return setup_group(grp); +#else + return Qnil; +#endif +} + +static VALUE +etc_group(obj) + VALUE obj; +{ +#ifdef HAVE_GETGRENT + struct group *grp; + + if (iterator_p()) { + setgrent(); + while (grp = getgrent()) { + rb_yield(setup_group(grp)); + } + endgrent(); + return obj; + } + return setup_group(getgrent()); +#else + return Qnil; +#endif +} + +VALUE mEtc; + +void +Init_etc() +{ + mEtc = rb_define_module("Etc"); + + rb_define_module_function(mEtc, "getlogin", etc_getlogin, 0); + + rb_define_module_function(mEtc, "getpwuid", etc_getpwuid, -1); + rb_define_module_function(mEtc, "getpwnam", etc_getpwnam, 1); + rb_define_module_function(mEtc, "passwd", etc_passwd, 0); + + rb_define_module_function(mEtc, "getgrgid", etc_getgrgid, 1); + rb_define_module_function(mEtc, "getgrnam", etc_getgrnam, 1); + rb_define_module_function(mEtc, "group", etc_group, 0); + + sPasswd = struct_define("Passwd", + "name", "passwd", "uid", "gid", + "gecos", "dir", "shell", +#ifdef PW_CHANGE + "change", +#endif +#ifdef PW_QUOTA + "quota", +#endif +#ifdef PW_AGE + "age", +#endif +#ifdef PW_CLASS + "class", +#endif +#ifdef PW_COMMENT + "comment", +#endif +#ifdef PW_EXPIRE + "expire", +#endif + Qnil); + +#ifdef HAVE_GETGRENT + sGroup = struct_define("Group", "name", "passwd", "gid", "mem", Qnil); +#endif +} diff --git a/ext/etc/etc.doc b/ext/etc/etc.doc new file mode 100644 index 0000000000..2af895c9de --- /dev/null +++ b/ext/etc/etc.doc @@ -0,0 +1,73 @@ +.\" etc.doc - -*- Indented-Text -*- created at: Fri Jul 14 00:47:15 JST 1995 + +** Etc(�⥸�塼��) + +/etc�ǥ��쥯�ȥ�ʲ��ξ�������뤿��Υ⥸�塼�롥���饹�˥��롼�� +���ƻȤ����Ȥ�Ǥ��롥 + +Methods: +Single Methods: + + getlogin + + ��ʬ��login̾���֤������줬���Ԥ�������getpwuid()���Ѥ���� + �ɤ��� + + getpwnam(name) + + /etc/passwd�ե�����(���뤤��DBM�ե������NIS�ǡ����١���)�� + ������name��̾�������passwd����ȥ���֤�������ͤ�passwd��¤ + �Τǰʲ��Υ��Ф���ġ� + + struct passwd + name # �桼��̾(ʸ����) + passwd # �ѥ����(ʸ����) + uid # �桼��ID(����) + gid # ���롼��ID(����) + gecos # gecos�ե������(ʸ����) + dir # �ۡ���ǥ��쥯�ȥ�(ʸ����) + shell # ����������(ʸ����) + # �ʹߤΥ��Фϥ����ƥ�ˤ�äƤ�����ʤ��� + change # �ѥ�����ѹ�����(����) + quota # ��������(����) + age # ������(����) + class # �桼�������������饹(ʸ����) + comment # ������(ʸ����) + expire # ���������ͭ������(����) + end + + �ܺ٤�getpwnam(3)�ȤΤ��ȡ� + + getpwuid([uid]) + + uid��桼��ID�Ȥ���passwd����ȥ���֤�������ͤ�getpwnam()�� + Ʊ�ͤǤ��롥�������ά�������ˤ�getuid()���ͤ��Ѥ��롥�ܺ٤� + getpwuid(3)�ȤΤ��ȡ� + + getgrgid(gid) + + /etc/group�ե�����(���뤤�ϡ�getpwnam����)������gid�롼 + ��ID�Ȥ��륰�롼�ץ���ȥ���֤�������ͤ�group��¤�Τǰʲ��� + ���Ф���ġ� + + struct group + name # ���롼��̾(ʸ����) + passwd # ���롼�פΥѥ����(ʸ����) + gid # ���롼��ID(����) + mem # ���롼�ץ���̾������ + end + + �ܺ٤�getgrgid(3)�ȤΤ��ȡ� + + getgrnam(name) + + name�Ȥ���̾���Υ��롼�ץ���ȥ���֤�������ͤ�getgrgid()��Ʊ + �ͤǤ��롥�ܺ٤�getgrnam(3)�ȡ� + + group + + ���ƤΥ��롼�ץ���ȥ���˥����������뤿��Υ��ƥ졼���� + + passwd + + ���Ƥ�passwd����ȥ���˥����������뤿��Υ��ƥ졼���� diff --git a/ext/etc/extconf.rb b/ext/etc/extconf.rb new file mode 100644 index 0000000000..884de93ec8 --- /dev/null +++ b/ext/etc/extconf.rb @@ -0,0 +1,7 @@ +have_library("sun", "getpwnam") # NIS (== YP) interface for IRIX 4 +a = have_func("getlogin") +b = have_func("getpwent") +c = have_func("getgrent") +if a or b or c + create_makefile("etc") +end diff --git a/ext/extmk.rb.in b/ext/extmk.rb.in index 25bf6b9027..b61ccd222f 100644 --- a/ext/extmk.rb.in +++ b/ext/extmk.rb.in @@ -1,10 +1,40 @@ #! /usr/local/bin/ruby +if $ARGV[0] == 'install' + $install = TRUE + $ARGV.shift +end + +if $ARGV[0] == 'clean' + $clean = TRUE + $ARGV.shift +end + +$cache_mod = FALSE; +$lib_cache = {} +$func_cache = {} +$hdr_cache = {} + +if File.exists?("config.cache") then + f = open("config.cache", "r") + while f.gets + case $_ + when /^lib: ([\w_]+) (yes|no)/ + $lib_cache[$1] = $2 + when /^func: ([\w_]+) (yes|no)/ + $func_cache[$1] = $2 + when /^hdr: (.+) (yes|no)/ + $hdr_cache[$1] = $2 + end + end + f.close +end + def older(file1, file2) - if !File.exists(file1) then + if !File.exists?(file1) then return TRUE end - if !File.exists(file2) then + if !File.exists?(file2) then return FALSE end if File.mtime(file1) < File.mtime(file2) @@ -13,77 +43,144 @@ def older(file1, file2) return FALSE end -if !File.exists("./Makefile") || - older("./Makefile", "../extmk.rb") || - older("./Makefile", "./extconf.rb") then +LINK = "@CC@ -o conftest %s %s conftest.c %s > /dev/null 2>&1" +CPP = "@CPP@ @CPPFLAGS@ %s conftest.c > /dev/null 2>&1" - LINK = "@CC@ -o conftest @CFLAGS@ @LDFLAGS@ conftest.c %s > /dev/null 2>&1" - $defs = [] +def have_library(lib, func) + if $lib_cache[lib] + if $lib_cache[lib] == "yes" + if $libs + $libs = $libs + " -l" + lib + else + $libs = "-l" + lib + end + return TRUE + else + return FALSE + end + end - def have_library(func, lib) - cfile = open("conftest.c", "w") - printf cfile, "\ + cfile = open("conftest.c", "w") + printf cfile, "\ int main() { return 0; } int t() { %s(); return 0; } ", func - cfile.close - - begin - if system(format(LINK, "-l" + lib)) != 0 - return FALSE - end - ensure - system "/bin/rm -f conftest*" - end + cfile.close + begin if $libs - $libs = $libs + " -l" + lib + libs = "-l" + lib + " " + $libs else - $libs = "-l" + lib + libs = "-l" + lib end - $defs.push(format("-DHAVE_LIB%s", lib.toupper)) - return TRUE + if !system(format(LINK, $CFLAGS, $LDFLAGS, libs)) + $lib_cache[lib] = 'no' + $cache_mod = TRUE + return FALSE + end + ensure + system "/bin/rm -f conftest*" end - def have_func(func) + $libs = libs + $lib_cache[lib] = 'yes' + $cache_mod = TRUE + return TRUE +end - cfile = open("conftest.c", "w") - printf cfile, "\ +def have_func(func) + if $func_cache[func] + if $func_cache[func] == "yes" + $defs.push(format("-DHAVE_%s", func.upcase)) + return TRUE + else + return FALSE + end + end + + cfile = open("conftest.c", "w") + printf cfile, "\ char %s(); int main() { return 0; } int t() { %s(); return 0; } ", func, func - cfile.close + cfile.close - libs = $libs - libs = "" if libs == nil + libs = $libs + libs = "" if libs == nil - begin - if system(format(LINK, libs)) != 0 - return FALSE - end - ensure - system "/bin/rm -f conftest*" + begin + if !system(format(LINK, $CFLAGS, $LDFLAGS, libs)) + $func_cache[func] = 'no' + $cache_mod = TRUE + return FALSE end - $defs.push(format("-DHAVE_%s", func.toupper)) - return TRUE + ensure + system "/bin/rm -f conftest*" + end + $defs.push(format("-DHAVE_%s", func.upcase)) + $func_cache[func] = 'yes' + $cache_mod = TRUE + return TRUE +end +def have_header(header) + if $hdr_cache[header] + if $hdr_cache[header] == "yes" + header.tr!("a-z./\055", "A-Z___") + $defs.push(format("-DHAVE_%s", header)) + return TRUE + else + return FALSE + end end - def create_header() - if $defs.length > 0 - hfile = open("extconf.h", "w") - for line in $defs - line =~ /^-D(.*)/ - printf hfile, "#define %s 1\n", $1 - end - hfile.close + cfile = open("conftest.c", "w") + printf cfile, "\ +#include <%s> +", header + cfile.close + + begin + if !system(format(CPP, $CFLAGS)) + $hdr_cache[header] = 'no' + $cache_mod = TRUE + return FALSE end + ensure + system "/bin/rm -f conftest*" end + $hdr_cache[header] = 'yes' + header.tr!("a-z./\055", "A-Z___") + $defs.push(format("-DHAVE_%s", header)) + $cache_mod = TRUE + return TRUE +end - def create_makefile(target) - mfile = open("Makefile", "w") - printf mfile, "\ +def create_header() + if $defs.length > 0 + hfile = open("extconf.h", "w") + for line in $defs + line =~ /^-D(.*)/ + printf hfile, "#define %s 1\n", $1 + end + hfile.close + end +end + +def create_makefile(target) + + if $libs and "@DLEXT@" == "o" + libs = $libs.split + for lib in libs + lib.sub!(/-l(.*)/, '"lib\1.a"') + end + $defs.push(format("-DEXTLIB='%s'", libs.join(","))) + end + $libs = "" if not $libs + + mfile = open("Makefile", "w") + printf mfile, "\ SHELL = /bin/sh #### Start of system configuration section. #### @@ -93,84 +190,205 @@ VPATH = @srcdir@ CC = @CC@ -CFLAGS = -I../.. @CCDLFLAGS@ @CFLAGS@ %s -LDDLFLAGS = @LDDLFLAGS@ -", $defs.join(" ") +CFLAGS = %s #$CFLAGS %s +LDSHARED = @LDSHARED@ +", if $static then "" else "@CCDLFLAGS@" end, $defs.join(" ") - printf mfile, "\ + printf mfile, "\ prefix = @prefix@ binprefix = exec_prefix = @exec_prefix@ bindir = $(exec_prefix)/bin +libdir = @prefix@/lib/ruby @SET_MAKE@ #### End of system configuration section. #### " - printf mfile, "OBJS = " - if !$objs then - $objs = Dir["*.c"] - for f in $objs - f.sub(/\.c$/, ".o") - end + printf mfile, "LIBS = %s\n", $libs + printf mfile, "OBJS = " + if !$objs then + $objs = Dir["*.c"] + for f in $objs + f.sub!(/\.c$/, ".o") end - printf mfile, $objs.join(" ") - printf mfile, "\n" + end + printf mfile, $objs.join(" ") + printf mfile, "\n" - printf mfile, "\ -TARGET = %s.@DLEXT@ + printf mfile, "\ +TARGET = %s.%s + +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ all: $(TARGET) -clean:; @rm -f *.o *.so +clean:; @rm -f *.o *.so *.sl @rm -f Makefile extconf.h conftest.* @rm -f core ruby *~ realclean: clean -", target +", target, if $static then "o" else "@DLEXT@" end + + if !$static + printf mfile, "\ + +install: $(libdir)/$(TARGET) + +$(libdir)/$(TARGET): $(TARGET) + @test -d $(libdir) || mkdir $(libdir) + $(INSTALL_DATA) $(TARGET) $(libdir)/$(TARGET) +" + else + printf mfile, "\ - if "@DLEXT@" == "so" - printf mfile, "\ -.SUFFIXES: .so $(SUFFIXES) +install:; +" + end -$(TARGET).so: $(OBJS) - ld $(LDDLFLAGS) -o $*.so $(OBJS) + if !$static && "@DLEXT@" != "o" + printf mfile, "\ +$(TARGET): $(OBJS) + $(LDSHARED) -o $(TARGET) $(OBJS) $(LIBS) " - elsif !File.exists(target + ".c") - printf mfile, "\ -$(TARGET).o: $(OBJS) - ld $(LDDLFLAGS) -r $*.o $(OBJS) + elsif !File.exists?(target + ".c") + printf mfile, "\ +$(TARGET): $(OBJS) + ld $(LDDLFLAGS) -r $(TARGET) $(OBJS) " + end + + if File.exists?("depend") + dfile = open("depend", "r") + printf mfile, "###\n" + while line = dfile.gets() + printf mfile, "%s", line end + dfile.close + end + mfile.close + if $static + $extinit += format("\ +\tInit_%s();\n\ +\trb_provide(\"%s.o\");\n\ +", target, target) + $extobjs += format("ext/%s/%s.o ", $static, target) + end +end - if File.exists("depend") - dfile = open("depend", "r") - printf mfile, "###\n" - while line = dfile.gets() - printf mfile, "%s", line +def extmake(target) + if $static_ext[target] + $static = target + else + $static = FALSE + end + + return if $nodynamic and not $static + + $libs = nil + $objs = nil + $CFLAGS = "-I../.. @CFLAGS@" + $LDFLAGS = "@STATIC@ @LDFLAGS@" + + begin + Dir.chdir target + if $static_ext.size > 0 || + !File.exists?("./Makefile") || + older("./Makefile", "../Setup") || + older("./Makefile", "../extmk.rb") || + older("./Makefile", "./extconf.rb") + then + $defs = [] + if File.exists?("extconf.rb") + load "extconf.rb" + else + create_makefile(target); + end + end + if File.exists?("./Makefile") + if $install + system "make install" + elsif $clean + system "make clean" + else + system "make all" end - dfile.close end - mfile.close + $extlibs += " " + $libs if $static && $libs + ensure + Dir.chdir ".." end +end - if File.exists("configure") && - (!File.exists("config.status") || - File.mtime("config.status") < File.mtime("configure")) then +# get static-link modules +$static_ext = {} +if File.file? "./Setup" + f = open("./Setup") + while f.gets() + $_.chop! + sub!(/#.*$/, '') + continue if /^\s*$/ + if /^option +nodynamic/ + $nodynamic = TRUE + continue + end + $static_ext[$_.split[0]] = TRUE + end + f.close +end - system "./configure" +for d in Dir["*"] + File.directory?(d) || continue + File.file?(d + "/MANIFEST") || continue + + d = $1 if d =~ /\/([\/]*)$/ + print "compiling ", d, "\n" + extmake(d) +end + +if $cache_mod + f = open("config.cache", "w") + for k,v in $lib_cache + printf f, "lib: %s %s\n", k, v + end + for k,v in $func_cache + printf f, "func: %s %s\n", k, v end + for k,v in $hdr_cache + printf f, "hdr: %s %s\n", k, v + end + f.close +end - if File.exists("extconf.rb") - load "extconf.rb" - else - Dir.pwd =~ /[^\/]+$/ - create_makefile($&); +exit if $install +if $extobjs + if older("extinit.c", "Setup") + f = open("extinit.c", "w") + printf f, "void Init_ext() {\n" + printf f, $extinit + printf f, "}\n" + f.close + end + if older("extinit.o", "extinit.c") + cmd = "@CC@ @CFLAGS@ -c extinit.c" + print cmd, "\n" + system cmd or exit 1 end + Dir.chdir ".." + $extobjs = "ext/extinit.o " + $extobjs + + if older("ruby", "ext/Setup") or older("ruby", "miniruby") + `rm -f ruby` + end + system format('make ruby PROGRAM=ruby EXTOBJS="%s" EXTLIBS="%s"', $extobjs, $extlibs) +else + Dir.chdir ".." + `rm -f ruby` + `cp miniruby ruby` end -system "make all" if File.exists("./Makefile") #Local variables: # mode: ruby diff --git a/ext/marshal/MANIFEST b/ext/marshal/MANIFEST new file mode 100644 index 0000000000..53b0849484 --- /dev/null +++ b/ext/marshal/MANIFEST @@ -0,0 +1,4 @@ +MANIFEST +depend +marshal.c +marshal.doc diff --git a/ext/marshal/depend b/ext/marshal/depend new file mode 100644 index 0000000000..c955eb2d59 --- /dev/null +++ b/ext/marshal/depend @@ -0,0 +1,2 @@ +marshal.o: marshal.c ../../ruby.h ../../config.h ../../defines.h ../../io.h \ + ../../st.h diff --git a/ext/marshal/marshal.c b/ext/marshal/marshal.c new file mode 100644 index 0000000000..0b29ad5ab8 --- /dev/null +++ b/ext/marshal/marshal.c @@ -0,0 +1,565 @@ +/************************************************ + + marshal.c - + + $Author$ + $Revision$ + $Date$ + created at: Thu Apr 27 16:30:01 JST 1995 + +************************************************/ + +#include "ruby.h" +#include "io.h" +#include "st.h" + +#define TYPE_NIL '0' +#define TYPE_FIXNUM 'i' + +#define TYPE_OBJECT 'o' +#define TYPE_LINK '@' +#define TYPE_FLOAT 'f' +#define TYPE_BIGNUM 'l' +#define TYPE_STRING '"' +#define TYPE_REGEXP '/' +#define TYPE_ARRAY '[' +#define TYPE_HASH '{' +#define TYPE_STRUCT 'S' + +char *rb_class2path(); +VALUE rb_path2class(); + +static ID s_dump, s_load; + +#define w_byte(c, fp) putc((c), fp) +#define w_bytes(s, n, fp) (w_long((n), fp),fwrite(s, 1, n, fp)) + +static void +w_short(x, fp) + int x; + FILE *fp; +{ + w_byte( x & 0xff, fp); + w_byte((x>> 8) & 0xff, fp); +} + +static void +w_long(x, fp) + long x; + FILE *fp; +{ + w_byte((int)( x & 0xff), fp); + w_byte((int)((x>> 8) & 0xff), fp); + w_byte((int)((x>>16) & 0xff), fp); + w_byte((int)((x>>24) & 0xff), fp); +} + +static void +w_float(d, fp) + double d; + FILE *fp; +{ + char buf[100]; + + sprintf(buf, "%.12g", d); + w_bytes(buf, strlen(buf), fp); +} + +static void +w_symbol(id, fp) + ID id; + FILE *fp; +{ + char *sym = rb_id2name(id); + + w_bytes(sym, strlen(sym), fp); +} + +static void w_object(); +extern VALUE cBignum, cStruct; + +static int +hash_each(key, value, fp) + VALUE key, value; + FILE *fp; +{ + w_object(key, fp); + w_object(value, fp); + return ST_CONTINUE; +} + +static int +obj_each(id, value, fp) + ID id; + VALUE value; + FILE *fp; +{ + w_symbol(id, fp); + w_object(value, fp); + return ST_CONTINUE; +} + +struct st_table *new_idhash(); + +static void +w_object(obj, fp, port, table) + VALUE obj, port; + FILE *fp; + st_table *table; +{ + if (obj == Qnil) { + w_byte(TYPE_NIL, fp); + } + else if (FIXNUM_P(obj)) { + w_byte(TYPE_FIXNUM, fp); + w_long(FIX2INT(obj), fp); + } + else if (st_lookup(table, obj, 0)) { + w_byte(TYPE_LINK, fp); + w_long(obj, fp); + } + else { + st_insert(table, obj, 0); + switch (BUILTIN_TYPE(obj)) { + case T_FLOAT: + w_byte(TYPE_FLOAT, fp); + w_long(obj, fp); + w_float(RFLOAT(obj)->value, fp); + break; + + case T_BIGNUM: + w_byte(TYPE_BIGNUM, fp); + w_long(obj, fp); + { + char sign = RBIGNUM(obj)->sign?'+':'-'; + int len = RBIGNUM(obj)->len; + USHORT *d = RBIGNUM(obj)->digits; + + w_byte(sign, fp); + w_long(len, fp); + while (len--) { + w_short(d, fp); + d++; + } + } + break; + + case T_STRING: + w_byte(TYPE_STRING, fp); + w_long(obj, fp); + w_bytes(RSTRING(obj)->ptr, RSTRING(obj)->len, fp); + break; + + case T_REGEXP: + w_byte(TYPE_REGEXP, fp); + w_long(obj, fp); + w_bytes(RREGEXP(obj)->str, RREGEXP(obj)->len, fp); + w_byte(FL_TEST(obj, FL_USER1), fp); + break; + + case T_ARRAY: + w_byte(TYPE_ARRAY, fp); + w_long(obj, fp); + { + int len = RARRAY(obj)->len; + VALUE *ptr = RARRAY(obj)->ptr; + + w_long(len, fp); + while (len--) { + w_object(*ptr, fp, port, table); + ptr++; + } + } + break; + + case T_HASH: + w_byte(TYPE_HASH, fp); + w_long(obj, fp); + w_long(RHASH(obj)->tbl->num_entries, fp); + st_foreach(RHASH(obj)->tbl, hash_each, fp); + break; + + case T_STRUCT: + w_byte(TYPE_STRUCT, fp); + w_long(obj, fp); + { + int len = RSTRUCT(obj)->len; + char *path = rb_class2path(CLASS_OF(obj)); + VALUE mem; + int i; + + w_bytes(path, strlen(path), fp); + w_long(len, fp); + mem = rb_ivar_get(CLASS_OF(obj), rb_intern("__member__")); + if (mem == Qnil) { + Fail("non-initialized struct"); + } + for (i=0; i<len; i++) { + w_symbol(FIX2INT(RARRAY(mem)->ptr[i]), fp); + w_object(RSTRUCT(obj)->ptr[i], fp, port, table); + } + } + break; + + case T_OBJECT: + w_byte(TYPE_OBJECT, fp); + w_long(obj, fp); + { + VALUE class = CLASS_OF(obj); + char *path = rb_class2path(class); + + w_bytes(path, strlen(path), fp); + if (rb_responds_to(obj, s_dump)) { + w_long(-1, fp); + rb_funcall(obj, s_dump, 1, port); + } + else if (ROBJECT(obj)->iv_tbl) { + w_long(ROBJECT(obj)->iv_tbl->num_entries, fp); + st_foreach(ROBJECT(obj)->iv_tbl, obj_each, fp); + } + else { + w_long(0, fp); + } + } + break; + + default: + Fail("can't dump %s", rb_class2name(CLASS_OF(obj))); + break; + } + } +} + +static VALUE +marshal_dump(self, obj, port) + VALUE self, obj, port; +{ + extern VALUE cIO; + FILE *fp; + OpenFile *fptr; + st_table *table; + + if (obj_is_kind_of(port, cIO)) { + GetOpenFile(port, fptr); + if (!(fptr->mode & FMODE_WRITABLE)) { + Fail("not opened for writing"); + } + fp = (fptr->f2) ? fptr->f2 : fptr->f; + } + else { + Fail("instance of IO needed"); + } + + table = new_idhash(); + + w_object(obj, fp, port, table); + + st_free_table(table); + return Qnil; +} + +static VALUE +marshal_dumps(self, obj) + VALUE self, obj; +{ + VALUE str = str_new(0, 0); + VALUE port; + FILE *fp = Qnil; + char buf[BUFSIZ]; + int n; + + sprintf(buf, "/tmp/rb-mrsr-%x", getpid()^(int)buf); + port = file_open(buf, "w"); + if (!port) rb_sys_fail("tmp file"); + fp = fopen(buf, "r"); + if (!fp) rb_sys_fail("tmp file(read)"); + unlink(buf); + + marshal_dump(self, obj, port); + io_close(port); + + while (n = fread(buf, 1, BUFSIZ, fp)) { + str_cat(str, buf, n); + } + + return str; +} + +#define r_byte(fp) getc(fp) + +static int +r_short(fp) + FILE *fp; +{ + register short x; + x = r_byte(fp); + x |= r_byte(fp) << 8; + /* XXX If your short is > 16 bits, add sign-extension here!!! */ + return x; +} + +static long +r_long(fp) + FILE *fp; +{ + register long x; + x = r_byte(fp); + x |= (long)r_byte(fp) << 8; + x |= (long)r_byte(fp) << 16; + x |= (long)r_byte(fp) << 24; + /* XXX If your long is > 32 bits, add sign-extension here!!! */ + return x; +} +#define r_bytes(s, fp) r_bytes0(&s, fp) +static int +r_bytes0(s, fp) + char **s; + FILE *fp; +{ + int len = r_long(fp); + *s = ALLOC_N(char, len+1); + + fread(*s, 1, len, fp); + (*s)[len] = '\0'; + return len; +} + +static ID +r_symbol(fp) + FILE *fp; +{ + char *buf; + ID id; + + r_bytes(buf, fp); + id = rb_intern(buf); + free(buf); + return id; +} + +static VALUE +r_object(fp, port, table) + FILE *fp; + VALUE port; + st_table *table; +{ + VALUE v; + int type = r_byte(fp); + int id; + + switch (type) { + case EOF: + Fail("EOF read where object expected"); + return Qnil; + + case TYPE_NIL: + return Qnil; + + case TYPE_LINK: + if (st_lookup(table, r_long(fp), &v)) { + return v; + } + Fail("corrupted marshal file"); + break; + + case TYPE_FIXNUM: + { + int i = r_long(fp); + return INT2FIX(i); + } + } + + id = r_long(fp); + switch (type) { + case TYPE_FLOAT: + { + double atof(); + char *buf; + + r_bytes(buf, fp); + v = float_new(atof(buf)); + free(buf); + } + break; + + case TYPE_BIGNUM: + { + int len; + USHORT *digits; + + NEWOBJ(big, struct RBignum); + OBJSETUP(big, cBignum, T_BIGNUM); + big->sign = (r_byte(fp) == '+'); + big->len = len = r_long(fp); + big->digits = digits = ALLOC_N(USHORT, len); + while (len--) { + *digits++ = r_short(fp); + } + v = (VALUE)big; + } + break; + + case TYPE_STRING: + { + char *buf; + int len = r_bytes(buf, fp); + v = str_new(buf, len); + free(buf); + } + break; + + case TYPE_REGEXP: + { + char *buf; + int len = r_bytes(buf, fp); + int ci = r_byte(fp); + v = reg_new(buf, len, ci); + free(buf); + } + break; + + case TYPE_ARRAY: + { + int len = r_long(fp); + v = ary_new2(len); + while (len--) { + ary_push(v, r_object(fp, port, table)); + } + } + break; + + case TYPE_HASH: + { + int len = r_long(fp); + + v = hash_new(); + while (len--) { + VALUE key = r_object(fp, port, table); + VALUE value = r_object(fp, port, table); + hash_aset(v, key, value); + } + } + break; + + case TYPE_STRUCT: + { + VALUE class, mem, values; + char *path; + int i, len; + + r_bytes(path, fp); + class = rb_path2class(path); + free(path); + mem = rb_ivar_get(class, rb_intern("__member__")); + if (mem == Qnil) { + Fail("non-initialized struct"); + } + len = r_long(fp); + + values = ary_new(); + i = 0; + while (len--) { + ID slot = r_symbol(fp); + if (RARRAY(mem)->ptr[i++] != INT2FIX(slot)) + Fail("struct not compatible"); + ary_push(values, r_object(fp, port, table)); + } + v = struct_alloc(class, values); + } + break; + + case TYPE_OBJECT: + { + VALUE class; + int len; + char *path; + + r_bytes(path, fp); + class = rb_path2class(path); + free(path); + len = r_long(fp); + if (len == -1) { + if (rb_responds_to(class, s_load)) { + v = rb_funcall(class, s_load, 1, port); + } + else { + Fail("class %s needs to have method `_load_from'", + rb_class2name(class)); + } + } + else { + v = obj_alloc(class); + if (len > 0) { + while (len--) { + ID id = r_symbol(fp); + VALUE val = r_object(fp, port, table); + rb_ivar_set(v, id, val); + } + } + } + } + break; + + default: + Fail("dump format error(0x%x)", type); + break; + } + st_insert(table, id, v); + return v; +} + +static VALUE +marshal_load(self, port) + VALUE self, port; +{ + extern VALUE cIO; + void *fp; + VALUE v; + OpenFile *fptr; + st_table *table; + + if (TYPE(port) == T_STRING) { + char buf[32]; + + sprintf(buf, "/tmp/rb-mrsw-%x", getpid()^(int)buf); + fp = fopen(buf, "w"); + if (!fp) rb_sys_fail("tmp file"); + v = file_open(buf, "r"); + if (!v) rb_sys_fail("tmp file(read)"); + unlink(buf); + + fwrite(RSTRING(port)->ptr, RSTRING(port)->len, 1, fp); + fclose(fp); + port = v; + } + if (obj_is_kind_of(port, cIO)) { + GetOpenFile(port, fptr); + if (!(fptr->mode & FMODE_READABLE)) { + Fail("not opened for reading"); + } + fp = fptr->f; + } + else { + Fail("instance of IO needed"); + } + + table = new_idhash(); + + v = r_object(fp, port, table); + + st_free_table(table); + + return v; +} + +Init_marshal() +{ + VALUE mMarshal = rb_define_module("Marshal"); + + s_dump = rb_intern("_dump_to"); + s_load = rb_intern("_load_from"); + rb_define_module_function(mMarshal, "dump", marshal_dump, 2); + rb_define_module_function(mMarshal, "dumps", marshal_dumps, 1); + rb_define_module_function(mMarshal, "load", marshal_load, 1); + rb_define_module_function(mMarshal, "restore", marshal_load, 1); +} diff --git a/ext/marshal/marshal.doc b/ext/marshal/marshal.doc new file mode 100644 index 0000000000..8c3b63072e --- /dev/null +++ b/ext/marshal/marshal.doc @@ -0,0 +1,45 @@ +.\" marshal.doc - -*- Indented-Text -*- created at: Tue May 16 12:18:08 JST 1995 + +** Marshal(�⥸�塼��) + +ruby���֥������Ȥ�ե�����˽Ф����ꡤ�ɤߤ��٤����ꤹ�뵡ǽ���� +����⥸�塼�롥����ʬ�Υ��饹�Υ�����Ф������Ǥ��뤬���ե� +����ؤ��Բ�ǽ�ʥ��饹��¸�ߤ�(��:IO)�����Τ褦�ʥ��饹��Ф����� +������㳰��ȯ�������롥 + +Methods: +Single Methods: + + dump(obj, port) + + obj��Ƶ�Ū�˥ե�����˽Ф����ե�����˽Ф��ʤ����饹�Υ� + ����ե�����˽Ф����Ȥ�����㳰��ȯ�������롥�ե����� + �˽Ф��ʤ����饹�ϰʲ����̤ꡥ + + Class, Module, Data + + �ޤ��������Υ��饹�����Ū�˻ؤ����饹(�㤨��IO�Υ��֥��饹)�ʤ� + ��Ф��ʤ���port��IO(�ޤ��Ϥ��Υ��֥��饹)�Υ�������� + ���롥 + + ���Ϥ��륪�֥������Ȥ���å�`_dump_to'��������Ƥ�����ˤϡ��ե� + ������ϤϤ��Υ�åɤ�ȤäƹԤ��롥��å�`_dump_to'�ϰ����� + ���ƽ�����Υե����륪�֥������Ȥ������롥��������å� + `_dump_to'����ĥ��饹��ɬ��Ʊ���ե����ޥåȤ��ɤ��᤹�ðۥ�å� + `_load_from'���������ɬ�פ����롥 + + + dumps(obj) + + dump()���ե�����˽Ф��Τ�Ʊ�����Ƥ�ޤ�ʸ������֤��� + + load(port) + + port���饪�֥������Ȥ��ɤ߹������ơ����Υ��֥������Ȥ�Ʊ�����֤� + ��ĥ��֥������Ȥ��������롥port��ʸ����IO(�ޤ��Ϥ��Υ��֥��饹) + �Υ����Ǥ��롥 + +------------------------------------------------------- +Local variables: +fill-column: 70 +end: diff --git a/ext/socket/MANIFEST b/ext/socket/MANIFEST new file mode 100644 index 0000000000..836caada41 --- /dev/null +++ b/ext/socket/MANIFEST @@ -0,0 +1,5 @@ +MANIFEST +depend +extconf.rb +socket.c +socket.doc diff --git a/ext/socket/depend b/ext/socket/depend new file mode 100644 index 0000000000..e6ede5a411 --- /dev/null +++ b/ext/socket/depend @@ -0,0 +1 @@ +socket.o : socket.c ../../ruby.h ../../config.h ../../defines.h ../../io.h ../../sig.h diff --git a/ext/socket/extconf.rb b/ext/socket/extconf.rb new file mode 100644 index 0000000000..60d6deeb84 --- /dev/null +++ b/ext/socket/extconf.rb @@ -0,0 +1,6 @@ +have_library("inet", "gethostbyname") +have_library("socket", "socket") +have_header("sys/un.h") +if have_func("socket") + create_makefile("socket") +end diff --git a/ext/socket/socket.c b/ext/socket/socket.c new file mode 100644 index 0000000000..5671b2762c --- /dev/null +++ b/ext/socket/socket.c @@ -0,0 +1,785 @@ +/************************************************ + + socket.c - + + $Author: matz $ + $Date: 1995/01/10 10:42:55 $ + created at: Thu Mar 31 12:21:29 JST 1994 + +************************************************/ + +#include "ruby.h" +#include "io.h" +#include <stdio.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <netdb.h> +#include <errno.h> +#ifdef HAVE_SYS_UN_H +#include <sys/un.h> +#else +#undef AF_UNIX +#endif + +extern VALUE cIO; +VALUE cBasicSocket; +VALUE cTCPsocket; +VALUE cTCPserver; +#ifdef AF_UNIX +VALUE cUNIXsocket; +VALUE cUNIXserver; +#endif +VALUE cSocket; + +FILE *rb_fdopen(); +char *strdup(); + +#ifdef NT +static void +sock_finalize(fptr) + OpenFile *fptr; +{ + SOCKET s = fileno(fptr->f); + free(fptr->f); + free(fptr->f2); + closesocket(s); +} +#endif + +static VALUE +sock_new(class, fd) + VALUE class; + int fd; +{ + VALUE sock = obj_alloc(class); + OpenFile *fp; + + MakeOpenFile(sock, fp); +#ifdef NT + fp->finalize = sock_finalize; +#endif + 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 +bsock_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 +bsock_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 +bsock_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 +bsock_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 +bsock_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 +tcp_s_sock_open(class, host, serv) + VALUE class, host, serv; +{ + Check_Type(host, T_STRING); + return open_inet(class, host, serv, 0); +} + +static VALUE +tcp_svr_s_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 +s_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 +tcp_accept(sock) + VALUE sock; +{ + OpenFile *fptr; + struct sockaddr_in from; + int fromlen; + + GetOpenFile(sock, fptr); + fromlen = sizeof(struct sockaddr_in); + return s_accept(cTCPsocket, fileno(fptr->f), + (struct sockaddr*)&from, &fromlen); +} + +#ifdef AF_UNIX +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; +} +#endif + +static VALUE +tcpaddr(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 +tcp_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 tcpaddr(&addr); +} + +static VALUE +tcp_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 tcpaddr(&addr); +} + +#ifdef AF_UNIX +static VALUE +unix_s_sock_open(sock, path) + VALUE sock, path; +{ + return open_unix(sock, path, 0); +} + +static VALUE +unix_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 +unix_svr_s_open(class, path) + VALUE class, path; +{ + return open_unix(class, path, 1); +} + +static VALUE +unix_accept(sock) + VALUE sock; +{ + OpenFile *fptr; + struct sockaddr_un from; + int fromlen; + + GetOpenFile(sock, fptr); + fromlen = sizeof(struct sockaddr_un); + return s_accept(cUNIXsocket, fileno(fptr->f), + (struct sockaddr*)&from, &fromlen); +} + +static VALUE +unixaddr(sockaddr) + struct sockaddr_un *sockaddr; +{ + return assoc_new(str_new2("AF_UNIX"),str_new2(sockaddr->sun_path)); +} + +static VALUE +unix_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 unixaddr(&addr); +} + +static VALUE +unix_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 unixaddr(&addr); +} +#endif + +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_INET") == 0) + *dv = PF_INET; +#ifdef PF_UNIX + else if (strcmp(ptr, "PF_UNIX") == 0) + *dv = PF_UNIX; +#endif +#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 +sock_s_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 +sock_s_for_fd(class, fd) + VALUE class, fd; +{ + return sock_new(class, NUM2INT(fd)); +} + +static VALUE +sock_s_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 +sock_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 +sock_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 +sock_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 +sock_accept(sock) + VALUE sock; +{ + OpenFile *fptr; + VALUE addr, sock2; + char buf[1024]; + int len = sizeof buf; + + GetOpenFile(sock, fptr); + sock2 = s_accept(cSocket,fileno(fptr->f),(struct sockaddr*)buf,&len); + + return assoc_new(sock2, str_new(buf, len)); +} + +static VALUE +sock_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 +s_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 +sock_recv(argc, argv, sock) + int argc; + VALUE *argv; + VALUE sock; +{ + return s_recv(sock, argc, argv, 0); +} + +static VALUE +sock_recvfrom(argc, argv, sock) + int argc; + VALUE *argv; + VALUE sock; +{ + return s_recv(sock, argc, argv, 1); +} + +Init_socket () +{ + cBasicSocket = rb_define_class("BasicSocket", cIO); + rb_undef_method(cBasicSocket, "new"); + rb_define_method(cBasicSocket, "shutdown", bsock_shutdown, -1); + rb_define_method(cBasicSocket, "setopt", bsock_setopt, 3); + rb_define_method(cBasicSocket, "getopt", bsock_getopt, 2); + rb_define_method(cBasicSocket, "getsockname", bsock_getsockname, 0); + rb_define_method(cBasicSocket, "getpeername", bsock_getpeername, 0); + + cTCPsocket = rb_define_class("TCPsocket", cBasicSocket); + rb_define_singleton_method(cTCPsocket, "open", tcp_s_sock_open, 2); + rb_define_singleton_method(cTCPsocket, "new", tcp_s_sock_open, 2); + rb_define_method(cTCPsocket, "addr", tcp_addr, 0); + rb_define_method(cTCPsocket, "peeraddr", tcp_peeraddr, 0); + + cTCPserver = rb_define_class("TCPserver", cTCPsocket); + rb_define_singleton_method(cTCPserver, "open", tcp_svr_s_open, -1); + rb_define_singleton_method(cTCPserver, "new", tcp_svr_s_open, -1); + rb_define_method(cTCPserver, "accept", tcp_accept, 0); + +#ifdef AF_UNIX + cUNIXsocket = rb_define_class("UNIXsocket", cBasicSocket); + rb_define_singleton_method(cUNIXsocket, "open", unix_s_sock_open, 1); + rb_define_singleton_method(cUNIXsocket, "new", unix_s_sock_open, 1); + rb_define_method(cUNIXsocket, "path", unix_path, 0); + rb_define_method(cUNIXsocket, "addr", unix_addr, 0); + rb_define_method(cUNIXsocket, "peeraddr", unix_peeraddr, 0); + + cUNIXserver = rb_define_class("UNIXserver", cUNIXsocket); + rb_define_singleton_method(cUNIXserver, "open", unix_svr_s_open, 1); + rb_define_singleton_method(cUNIXserver, "new", unix_svr_s_open, 1); + rb_define_method(cUNIXserver, "accept", unix_accept, 0); +#endif + + cSocket = rb_define_class("Socket", cBasicSocket); + rb_define_singleton_method(cSocket, "open", sock_s_open, 3); + rb_define_singleton_method(cSocket, "new", sock_s_open, 3); + rb_define_singleton_method(cSocket, "for_fd", sock_s_for_fd, 1); + + rb_define_method(cSocket, "connect", sock_connect, 1); + rb_define_method(cSocket, "bind", sock_bind, 1); + rb_define_method(cSocket, "listen", sock_listen, 1); + rb_define_method(cSocket, "accept", sock_accept, 0); + + rb_define_method(cSocket, "send", sock_send, -1); + rb_define_method(cSocket, "recv", sock_recv, -1); + rb_define_method(cSocket, "recvfrom", sock_recv, -1); + + rb_define_singleton_method(cSocket, "socketpair", sock_s_socketpair, 3); +} diff --git a/ext/socket/socket.doc b/ext/socket/socket.doc new file mode 100644 index 0000000000..aa5bfedbff --- /dev/null +++ b/ext/socket/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)��Ʊ��Ư���롥addr��pack���줿�����åȥ��ɥ쥹��¤ + �ΤǤ��롥 + + connect(addr) + + connect(2)��Ʊ��Ư���롥addr��pack���줿�����åȥ��ɥ쥹�� + ¤�ΤǤ��롥 + + 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) + + �����������åȤ��������롥domain��type��protocol�ϥ��롼�� + �ե�������������Ƥ�������ͤǻ��ꤹ�롥domain��type�˴ؤ��� + �ϡ�ʸ����ǻ���Ǥ��뤬�����٤ƤС����Ƥ����ݾڤϤʤ��� + + 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) + + �����åȤΰʹߤ���³��λ�����롥how��0�Ǥ�������ʹߤμ������� + how��1�Ǥ�����ϡ��ʹߤ����������ݤ���롥how��2�λ��ˤϡ����� + �ʹߤ������������Ȥ�˵��ݤ���롥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: diff --git a/ext/tkutil/MANIFEST b/ext/tkutil/MANIFEST new file mode 100644 index 0000000000..98df4663b3 --- /dev/null +++ b/ext/tkutil/MANIFEST @@ -0,0 +1,3 @@ +MANIFEST +extconf.rb +tkutil.c diff --git a/ext/tkutil/extconf.rb b/ext/tkutil/extconf.rb new file mode 100644 index 0000000000..b61a7ac01c --- /dev/null +++ b/ext/tkutil/extconf.rb @@ -0,0 +1,11 @@ +for dir in ENV['PATH'].split(':') + if File.exists? "#{dir}/wish" + $CFLAGS = $CFLAGS + " -DWISHPATH=" + "'\"#{dir}/wish\"'" + have_wish = TRUE + break + end +end + +if have_wish and have_func('pipe') + create_makefile("tkutil") +end diff --git a/ext/tkutil/tkutil.c b/ext/tkutil/tkutil.c new file mode 100644 index 0000000000..2b74b254c2 --- /dev/null +++ b/ext/tkutil/tkutil.c @@ -0,0 +1,54 @@ +/************************************************ + + tk.c - + + $Author: matz $ + $Date: 1995/11/03 00:47:55 $ + created at: Fri Nov 3 00:47:54 JST 1995 + +************************************************/ + +#include "ruby.h" + +static VALUE +tk_eval_cmd(argc, argv) + int argc; + VALUE argv[]; +{ + VALUE cmd, rest; + + rb_scan_args(argc, argv, "1*", &cmd, &rest); + rb_eval_cmd(cmd, rest); + return Qnil; +} + +static VALUE +tk_yield(obj) + VALUE obj; +{ + rb_yield_0(obj, obj); +} + +static VALUE +tk_s_new(argc, argv, class) + int argc; + VALUE *argv; + VALUE class; +{ + VALUE obj = obj_alloc(class); + + rb_funcall2(obj, rb_intern("initialize"), argc, argv); + if (iterator_p()) tk_yield(obj); + return obj; +} + +Init_tkutil() +{ + VALUE mTK = rb_define_module("TkUtil"); + VALUE cTK = rb_define_class("TkKernel", cObject); + + rb_define_const(mTK, "WISH_PATH", str_new2(WISHPATH)); + rb_define_singleton_method(mTK, "eval_cmd", tk_eval_cmd, -1); + + rb_define_singleton_method(cTK, "new", tk_s_new, -1); +} |