最新のもの: Gauche:Bugs
2006/11/09 16:22:06 PST: got got は多分 but got ?
2006/11/03 14:08:31 PST: if (SCM_INTP(res)) が偽のとき、exit_code が未初期化のまま使われません?
2006/11/02 16:12:12 PST: 大した事じゃないんですが、http://practical-scheme.net/gauche/index-j.html のCVSへのリンクが、古いままになってます。
(いつのまにか、sf.netのアップデートで、 http://gauche.cvs.sourceforge.net/gauche/ に移動していたみたいです。)
2006/11/02 14:59:05 PST: doc/modgauche.texi の condition variable のスロットの説明の部分が
@defivar <mutex> name
のようになっています。
2006/11/02 14:31:04 PST: port.h rev. 1.15 の変更に関して。 元の意味は PORT_LOCKED() but !SCM_PORT_PRIVATE なら unwind protect だと思うので、
if (p->lockOwner != Scm_VM()) {
は条件が逆で、常に真だからいらないのではないでしょうか?
また、portapi.c で PORT_SAFE_CALL() が一箇所直に呼び出されています。
2006/11/02 14:47:25 PST: 二点、
(use gauche.threads)
(define (load-some-class)
(call-with-input-string "(define-class x () ())" load-from-port))
(define (thrmsg m) (format #t "thread ~a: ~a\n" (current-thread) m))
(let1 threads (map (lambda (name)
(thread-start! (make-thread (lambda ()
(thrmsg "start")
(load-some-class)
(thrmsg "loaded")
(sys-sleep 1)
(thrmsg "exiting"))
name)))
'("A" "B" "C"))
(sys-sleep 10)
(display "call gc\n")
(gc)
(for-each thread-join! threads))
Rui(2006/10/29 20:49:29 PST): applyと同様、末尾のevalが末尾呼び出しになりませんでした。
(define (loop) (eval '(loop) (current-module))) (loop)
Rui(2006/10/29 20:14:02 PST): 下記のコードがメモリを使い尽くそうとします。末尾のapplyが末尾呼び出しにならないようです。
(define (loop x) (apply loop (list x))) (loop 1)
Rui(2006/10/26 02:20:42 PDT): 循環リストを"equal?"タイプのハッシュテーブルに足そうとすると、hash-table-put!が返ってきませんでした。ツリーをトラバースして要素のハッシュ値を求めているので、そこでループに入ってしまうようです。どちらかといえばこれはドキュメント化するだけの話かもしれませんが。
Rui(2006/10/18 02:31:07 PDT): doc/modutil.texiの10904行目の"varx"は"var"の間違いです。修正しないとmakeinfoできませんでした。
2006/10/18 21:45:54 PDT:便乗。modsrfi.texi です。
-これは、Gauche の組み込み手続き @code{acon} の別名です。
+これは、Gauche の組み込み手続き @code{acons} の別名です。
2006/10/20 07:58:08 PDT: typo ではないかもしれないですが、ちょっと気になったこと:
Rui(2006/10/20 20:44:35 PDT): string-pointer-refがマニュアルにないようです。
2006/10/20 14:41:34 PDT:
Index: lib/Makefile.in
===================================================================
RCS file: /cvsroot/gauche/Gauche/lib/Makefile.in,v
retrieving revision 1.140
diff -u -r1.140 Makefile.in
--- lib/Makefile.in 16 Oct 2006 12:00:42 -0000 1.140
+++ lib/Makefile.in 20 Oct 2006 21:34:26 -0000
@@ -64,7 +64,7 @@
util/isomorph.scm util/toposort.scm util/queue.scm util/tree.scm
util/digest.scm util/combinations.scm util/lcs.scm util/list.scm
util/record.scm util/relation.scm util/stream.scm util/trie.scm
- compat/jfilter.scm compat/stk.scm compat/norationa.scm
+ compat/jfilter.scm compat/stk.scm compat/norational.scm
file/filter.scm
rfc/822.scm rfc/mime.scm rfc/base64.scm rfc/uri.scm rfc/cookie.scm
rfc/quoted-printable.scm rfc/http.scm rfc/hmac.scm
leque(2006/10/20 12:50:38 PDT): 0/0 や 0 除算がおかしな値になります。
gosh> (/ -1 0) #<nan> gosh> (/ 2 0) #<nan> gosh> 0/0 #i1/0 gosh> -1/0 #i-1/0 gosh> 1/0 #i1/0
Index: number.c
===================================================================
RCS file: /cvsroot/gauche/Gauche/src/number.c,v
retrieving revision 1.130
diff -u -r1.130 number.c
--- number.c 18 Oct 2006 10:59:52 -0000 1.130
+++ number.c 20 Oct 2006 19:45:44 -0000
@@ -1670,7 +1670,7 @@
}
ANORMAL:
{
- int s = SCM_EXACT_ZERO_P(arg0);
+ int s = Scm_Sign(arg0);
if (s == 0) return SCM_NAN;
if (s < 0) return SCM_NEGATIVE_INFINITY;
else return SCM_POSITIVE_INFINITY;
@@ -3060,9 +3060,10 @@
if (SCM_EXACT_ZERO_P(denom)) {
if (lensave > *lenp) {
if (ctx->exactness == EXACT) {
- return numread_error("(exact infinity is not supported.)",
+ return numread_error("(exact infinity/nan is not supported.)",
ctx);
}
+ if (SCM_EXACT_ZERO_P(intpart)) return SCM_NAN;
return minusp? SCM_NEGATIVE_INFINITY:SCM_POSITIVE_INFINITY;
} else {
return SCM_FALSE;
Rui(2006/10/19 01:42:02 PDT): 私の環境(Ubuntu 6.06)ではIPv6のループバックアドレスはip6-localhostという名前で、localhostという名前はIPv4にしか与えられていません。IPv6をサポートしているのにlocalhostが解決できないので、ext/net/test.scmの216行目のテストに失敗してしまいます。最初からそんな/etc/hostsになっていて、あまり変な環境でもないと思うのですが……。
(and-let* ((sock (any (lambda (name)
(guard (e (else #f))
(make-client-socket (make (if (global-variable-bound? 'gauche.net
'<sockaddr-in6>)
<sockaddr-in6>
<sockaddr-in>)
:host name :port *inet-port*))))
'("localhost" "ip6-localhost" "ipv6-localhost"))))
(test* "inet client socket" #t
(call-with-client-socket sock
(lambda (in out)
(display (make-string *chunk-size* #\a) out)
(newline out)
(flush out)
(string=? (read-line in) (make-string *chunk-size* #\A))))))
Rui(2006/10/19 00:03:07 PDT): ext/net/netlib.stubはScm_MakeBignumFromUIArrayを使っているのですが、gauche/bignum.hをインクルードしていません。
Rui(2006/10/18 23:17:54 PDT): LANGがja_JP.UTF-8な環境だと、makeinfoが「これは gauche-refj.info、gauche-refj.texi より makeinfoバージョン 4.8 によって作成されました。」というUTF-8な文字列をinfoの先頭に挿入するので、gauche-refj.infoのEUC-JPな文字列が壊れてしまいます。LANGをunsetしてmakeinfoするようにしてもらえないでしょうか。
Rui(2006/10/18 22:30:01 PDT): ext/sxml/sxml-tools.cはsxml.sxpathに依存しているので、Makefileに依存関係を追加してください。クリーンな状態からのmakeに失敗しました。ext/sxml/Makefile.inの70行目にsxml-sxpath.$(SOEXT)を足せばよいと思います。
Rui(2006/10/17 22:07:38 PDT): 指数部の大きな数字のreadに問題があるようです。
gosh> 1e1000 "number.c", line 2460 (iexpt10): Assertion failed: e < IEXPT10_TABLESIZ
tabe(2006/10/18 00:41:09 PDT): 別の境界の例です(0.8.7)。
gosh> 1e308 1.0e308 gosh> 1e309 *** ERROR: exact integer required, but got #t Stack Trace: _______________________________________
gosh> 1e309 #i1/0 gosh> -1e1000 #i-1/0 gosh> 1e-1000 0.0 gosh> #e12.34 617/50 gosh> #e1e-10 1/10000000000 gosh> #e1e100000 *** ERROR: bad number format (such an exact number is out of implementation limitation): #e1e100000
2006/10/10 21:01:31 PDT: tried_gc には TRUE/FALSE しか代入されていないので、tried_gc > 10 は変です。
lib/rfc/cookie.scm 217行目付近ですが、
((eqv? :expires (car attr))
(if (> ver 0)
(ignore)
(next (make-expires-attr (cadr attr)))))
は
((eqv? :expires (car attr))
(if (> ver 0)
(next (make-expires-attr (cadr attr)))
(ignore)))
にしたら、正しく動きました。
ところで、make-expires-attrは、要素が整数の場合、自動的に日付に変換してくれますが、このあたりを<time>とかsrfi-19 dateとかもcookieの日付書法で変換してくれると嬉しいと思います。2006/09/30 19:10:50 PDT
2006/09/18 23:54:42 PDT: src/write.c に二箇所ある
Scm_Error("incomplete %-directive in format string: %s", fmt);
は、Scm_Error() が結局 Scm_Vprintf() を呼ぶので %%-directive でないとまずそうです。
2006/08/29 01:54:38 PDT: リファレンス中にtypoがありました。
Index: doc/modgauche.texi
===================================================================
RCS file: /cvsroot/gauche/Gauche/doc/modgauche.texi,v
retrieving revision 1.74
diff -u -r1.74 modgauche.texi
--- doc/modgauche.texi 28 May 2006 02:31:14 -0000 1.74
+++ doc/modgauche.texi 29 Aug 2006 08:52:03 -0000
@@ -7947,7 +7947,7 @@
(@var{compare} @var{expected} @var{result-of-thunk})
@end example
この手続きは、渡された結果が期待する値と合致する場合に@code{#t}を、
-そうでなければ@code{#t}を返さなければなりません。
+そうでなければ@code{#f}を返さなければなりません。
特別な比較手続きのひとつの用法は、不正確な数値を、多少の誤差を許して
比較するような場合です。
@c COMMON
Index: doc/object.texi
===================================================================
RCS file: /cvsroot/gauche/Gauche/doc/object.texi,v
retrieving revision 1.40
diff -u -r1.40 object.texi
--- doc/object.texi 11 Mar 2006 13:07:35 -0000 1.40
+++ doc/object.texi 29 Aug 2006 08:52:03 -0000
@@ -3140,7 +3140,7 @@
ディスパッチし呼び出すか、これらはすべてオブジェクトシステムによって、
定義されます。たとえば、クラスはジェネリックな構造と標準的クラスの
振舞いを定義する @code{<class>} クラスのインスタンスです。@code{<class>}
-のサブクラス化すると、デフォルトのものとは違う振舞いをする、独自の
+をサブクラス化すると、デフォルトのものとは違う振舞いをする、独自の
クラス集合をつくることができます。これは結局、独自のオブジェクトシステムを
つくることになります。
び(2006/08/14 02:03:20 PDT): 現在の実装だと、指定したエンコーディングと内部エンコーディングの間で変換が不要であっても変換ポートを作ってしまいます。
Index: ext/charconv/convaux.scm
===================================================================
RCS file: /cvsroot/gauche/Gauche/ext/charconv/convaux.scm,v
retrieving revision 1.1
diff -u -r1.1 convaux.scm
--- ext/charconv/convaux.scm 10 Sep 2005 09:04:04 -0000 1.1
+++ ext/charconv/convaux.scm 14 Aug 2006 08:48:58 -0000
@@ -184,7 +184,7 @@
;; open-{input|output}-port when :encoding argument is given.
(define (%open-input-file/conv name . args)
(and-let* ((port (apply %open-input-file name args)))
- (open-input-conversion-port
+ (wrap-with-input-conversion
port
(get-keyword :encoding args #f)
:buffer-size (get-keyword :conversion-buffer-size args 0)
@@ -192,7 +192,7 @@
(define (%open-output-file/conv name . args)
(and-let* ((port (apply %open-output-file name args)))
- (open-output-conversion-port
+ (wrap-with-output-conversion
port
(get-keyword :encoding args #f)
:buffer-size (get-keyword :conversion-buffer-size args 0)
タイポだと思います.
--- src/compile.scm-orig 2006年 8月 5日 (土) +++ src/compile.scm 2006年 8月 5日 (土) @@ -64,7 +64,7 @@ ;;; ;;; Pass 2 (Optimization): ;;; - Traverses IFrom and modify the tree to optimize it. -;;; - Limited beta-sustitution (local variable substitution and +;;; - Limited beta-substitution (local variable substitution and ;;; inline local functions for the obvious cases). ;;; - Closure optimization (generates efficient code for truly local ;;; closures)
isi(2006/08/02 06:56:08 PDT): ユーザ・リファレンスに「...パラメータnameに対応する値が無ければ、defaultに与えられた値がそのまま返されます。...」と説明があるため、nameだけが定義されていて、値が定義されていない(name=value ではなく name となっている)場合のデフォルト値だと思ったのですが、実装は name そのものが定義されていない場合のデフォルト値となっています。どちらが正しいですか?
2006/07/09 20:40:47 PDT
CSV 形式は、「正式な」仕様が無さそうなのにも関わらず、 プレーン・テキストで表形式のデータを交換するために広く使われています。
現在ではRFC4180で定義されているようなのでその旨を追記しておいた方がよいのではないでしょうか?
tabe(2006/06/22 03:00:12 PDT): 手続き string-rindex が定義されていないようです。
gosh> (use sxml.sxpath) #<undef> gosh> ((sxpath '((ns-id:* x))) '(*TOP* y)) *** ERROR: unbound variable: string-rindex Stack Trace: _______________________________________
び(2006/06/11 22:23:55 PDT): dbi-parse-dsn はオプション文字列が存在しない場合、DSNとして"dbi:foo" は許容しますが "dbi:foo:" は許容しません。一方、「Older API」とコメントされている dbi-make-connection の実装では、オプションが空の時、"dbi:foo:" を引数として dbi-connect を(つまりその中でdbi-parse-dsn)呼び出しています。どちらを直すのがいいか判断に迷いますが、"dbi:foo:" も "dbi:foo" も同じと見なしても害はないように思いましたので、dbi-parse-dsn を直してみました。
Index: lib/dbi.scm
===================================================================
RCS file: /cvsroot/gauche/Gauche/lib/dbi.scm,v
retrieving revision 1.32
diff -u -r1.32 dbi.scm
--- lib/dbi.scm 9 Mar 2006 21:53:06 -0000 1.32
+++ lib/dbi.scm 12 Jun 2006 05:17:41 -0000
@@ -204,14 +204,14 @@
;;
(define (dbi-parse-dsn data-source-name)
(rxmatch-case data-source-name
- (#/^dbi:([\w-]+)(?::(.+))?$/ (#f driver options)
- (if options
- (let1 alist (map (lambda (nv)
- (receive (n v) (string-scan nv "=" 'both)
- (if n (cons n v) (cons nv #t))))
- (string-split options #\;))
- (values driver options alist))
- (values driver "" '())))
+ (#/^dbi:([\w-]+)(?::(.*))?$/ (#f driver options)
+ (if (and options (not (string-null? options)))
+ (let1 alist (map (lambda (nv)
+ (receive (n v) (string-scan nv "=" 'both)
+ (if n (cons n v) (cons nv #t))))
+ (string-split options #\;))
+ (values driver options alist))
+ (values driver "" '())))
(else
(error <dbi-error> "bad data source name spec:" data-source-name))))
horii(2006/05/31 02:04:28 PDT): カテゴリが SCM_CLASS_BASE のクラスは、構造体の最初のメンバが ScmInstance でないといけないと思っているのですが、ScmConditionVariableRec と ScmMutexRec だけは、そうなっていません。
--- threads.h.orig 2006-05-31 17:54:51.266058922 +0900
+++ threads.h 2006-05-31 17:54:58.000000000 +0900
@@ -59,7 +59,7 @@
* Scheme condition variable.
*/
typedef struct ScmConditionVariableRec {
- SCM_HEADER;
+ SCM_INSTANCE_HEADER;
ScmInternalCond cv;
ScmObj name;
ScmObj specific;
@@ -82,7 +82,7 @@
* locked=TRUE owner=terminated vm unlocked/abandoned
*/
typedef struct ScmMutexRec {
- SCM_HEADER;
+ SCM_INSTANCE_HEADER;
ScmInternalMutex mutex;
ScmInternalCond cv;
ScmObj name;
./configure --prefix=$HOME --enable-threads=pthreads~% make~% make check~% Testing threads ... /bin/sh: line 1: 5497 セグメンテーション違反です ../..//src/gosh -ftest -I. test.scm >test.log~%
test.logは
test write to file, buffered, expects #t ==>で終っています。
何度かやるとたまに成功します。
gdbで見たところ、
Program received signal SIGSEGV, Segmentation fault. [Switching to Thread -1229931600 (LWP 7331)] 0x00e6a957 in Scm_Write (obj=0x8759240, p=0x8a487e8, mode=1) at write.c:160 160 PORT_LOCK(port, vm);
となっていました。
環境は以下のとおりです。
uname -a 2.6.9-34.ELsmp #1 SMP Fri Feb 24 16:54:53 EST 2006 i686 i686 i386 GNU/Linux gcc -v /usr/lib/gcc/i386-redhat-linux/3.4.5/specs から spec を読み込み中 コンフィグオプション: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-checking --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-java-awt=gtk --host=i386-redhat-linux
追記:PORT_LOCKの
while (p->lockOwner != NULL) {
if (p->lockOwner->state == SCM_VM_TERMINATED) {
この行の間でlockOwnerがNULLになることがあるようです。
Index: src/gauche/port.h
===================================================================
RCS file: /cvsroot/gauche/Gauche/src/gauche/port.h,v
retrieving revision 1.11
diff -u -r1.11 port.h
--- src/gauche/port.h 17 Oct 2004 10:29:39 -0000 1.11
+++ src/gauche/port.h 31 May 2006 01:25:05 -0000
@@ -79,9 +79,10 @@
do { \
if (!(p->flags&SCM_PORT_PRIVATE)) { \
if (p->lockOwner != vm) { \
+ ScmVM *lockOwner = NULL; \
(void)SCM_INTERNAL_MUTEX_LOCK(p->mutex); \
- while (p->lockOwner != NULL) { \
- if (p->lockOwner->state == SCM_VM_TERMINATED) { \
+ while ((lockOwner = p->lockOwner) != NULL) { \
+ if (lockOwner->state == SCM_VM_TERMINATED) { \
break; \
} \
(void)SCM_INTERNAL_COND_WAIT(p->cv, p->mutex); \
yokota(2006/05/27 18:29:51 PDT): 最近の autoconf(Ver.2.59d) は可能な限り新しいC言語規格を使用しようとして C99 標準を使わせるオプションを設定しようとします。例えば gcc なら CC="gcc -std=gnu99" としようとします。 gauche-package は CC の値を引用符で囲んで使用しようとするために "gcc -std=gnu99" というコマンドは存在しないというエラーを出します。 結果として gauche-package を用いる全てのパッケージの構築に失敗します。 以下のパッチを当てて下さい。
--- Gauche-0.8.7/lib/gauche/package/compile.scm.orig 2005-08-01 13:24:03.000000000 +0900
+++ Gauche-0.8.7/lib/gauche/package/compile.scm 2006-05-28 10:19:02.000000000 +0900
@@ -87,7 +87,7 @@
(run #`"',GOSH' genstub ,stubfile"))
(define (do-compile cc cfile ofile cppflags cflags)
- (run #`"',cc' -c ,cppflags ,INCDIR ,cflags ,CFLAGS -o ',ofile' ',cfile'"))
+ (run #`",cc -c ,cppflags ,INCDIR ,cflags ,CFLAGS -o ',ofile' ',cfile'"))
(define (gauche-package-link sofile ofiles . args)
(let-keywords* args ((ldflags #f)
@@ -100,7 +100,7 @@
(unless (and (file-exists? sofile)
(every (cut file-mtime>? sofile <>) ofiles))
(let1 all-ofiles (string-join (map (lambda (f) #`"',f'") ofiles) " ")
- (run #`"',(or ld CC)' ,(or ldflags \"\") ,LIBDIR ,LDFLAGS ,sofile ,all-ofiles ,LIBS ,(or libs \"\")"))))))
+ (run #`",(or ld CC) ,(or ldflags \"\") ,LIBDIR ,LDFLAGS ,sofile ,all-ofiles ,LIBS ,(or libs \"\")"))))))
(define (gauche-package-compile-and-link module-name files . args)
(let ((head.c #`",|module-name|_head.c")
2006/05/22 08:44:45 PDT 標準モジュール rfc.http の http-post を使用すると、 リクエストのメッセージボディの後に余分なCRLFが送信されます。 RFC2616( ftp://ftp.isi.edu/in-notes/rfc2616.txt )の 4.1 Message Types によると
Certain buggy HTTP/1.0 client implementations generate extra CRLF's after a POST request. To restate what is explicitly forbidden by the BNF, an HTTP/1.1 client MUST NOT preface or follow a request with an extra CRLF.
ということなのでCRLFは送信しないほうが正確な挙動だと思います。 http.scm のへのパッチ
--- Gauche-0.8.7/lib/rfc/http.scm.orig 2006-05-22 14:44:39.111930696 +0900
+++ Gauche-0.8.7/lib/rfc/http.scm 2006-05-22 23:08:03.393366544 +0900
@@ -177,7 +177,7 @@
out)
(display "\r\n" out)
(display body out)
- (display "\r\n" out))
+ (flush out))
;; requests w/o body
(begin
(send-request-headers options out)
2006/05/19 20:40:44 PDT: leque いくつかのパターンで regexp-compile が失敗します。
gosh> (string->regexp "a+") #/a+/ gosh> (regexp-parse "a+") (0 #f (rep 1 #f #〓a)) gosh> (regexp-compile (regexp-parse "a+")) *** ERROR: internal error in regexp compilation: bad node: ((rep 1 #f ()))
gosh> (regexp-parse "a?+") (0 #f (once (rep 0 1 #〓a))) gosh> (regexp-compile (regexp-parse "a?+")) *** ERROR: invalid regexp AST: (once (rep 0 1 #〓a)) gosh> (regexp-parse "(a)〓〓1") (0 #f (1 #f #〓a) (backref . 1)) gosh> (regexp-compile (regexp-parse "(a)〓〓1")) *** ERROR: invalid regexp AST: (backref . 1) gosh> (regexp-parse "(?<hoge>a)〓〓k<hoge>") (0 #f (1 hoge #〓a) (backref . 1)) gosh> (regexp-compile (regexp-parse "(?<hoge>a)〓〓k<hoge>")) *** ERROR: invalid regexp AST: (backref . 1) gosh> (regexp-parse "(a)(?(1)b|c)") (0 #f (1 #f #〓a) (cpat 1 (#〓b) (#〓c))) gosh> (regexp-compile (regexp-parse "(a)(?(1)b|c)")) *** ERROR: invalid regexp AST: (cpat 1 (#〓b) (#〓c))
2006/05/13 03:40:18 PDT: http://www.shiro.dreamhost.com/scheme/gauche/man/gauche-refj_84.html#SEC244 の let-args の説明で, 「束縛リストは、最後のcarにシンボルを持つ不完全なリストであっても良く」 は cdr の typo でしょうか?
Rui (2006/05/13 02:53:20 PDT): object-writeの中でwrite/ssを呼ぶと、assertionに引っかかってgoshが落ちます。write/ssが呼ぶScm_WriteCircularで、walk passを意識せずwrite_ssを呼んでしまっているのが問題のようです。
び(2006/05/09 02:46:56 PDT): Mac OS Xでスレッドを多用すると瞬く間に仮想メモリ使用量が膨れ上がるのに、Linuxでは何ともないので不思議に思っていました。
--- ext/threads/threads.c.orig 2006-04-07 11:07:46.000000000 +0900
+++ ext/threads/threads.c 2006-05-09 18:33:04.000000000 +0900
@@ -165,7 +165,7 @@
SCM_ASSERT(vm->thunk);
vm->state = SCM_VM_RUNNABLE;
pthread_attr_init(&thattr);
- pthread_attr_setdetachstate(&thattr, TRUE);
+ pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_DETACHED);
pthread_sigmask(SIG_SETMASK, &threadrec.defaultSigmask, &omask);
if (pthread_create(&vm->thread, &thattr, thread_entry, vm) != 0) {
vm->state = SCM_VM_NEW;
Linuxだと
enum
{
PTHREAD_CREATE_JOINABLE,
#define PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_JOINABLE
PTHREAD_CREATE_DETACHED
#define PTHREAD_CREATE_DETACHED PTHREAD_CREATE_DETACHED
};
だからTRUEでも問題が起きないのだけど、Mac OS Xだと
#define PTHREAD_CREATE_JOINABLE 1 #define PTHREAD_CREATE_DETACHED 2
だからだめだったってことですね。
jingu(2006/05/01 00:33:05 PDT): ソケットオプションSO_RCVBUFが正しくエクスポートされていませんでした。 ついでに、SOL_SOCKETレベルでエクスポートされていないオプションも追加してみました。
diff -ru Gauche-0.8.7.orig/ext/net/netlib.stub Gauche-0.8.7/ext/net/netlib.stub --- Gauche-0.8.7.orig/ext/net/netlib.stub 2006-05-01 15:35:58.000000000 +0900 +++ Gauche-0.8.7/ext/net/netlib.stub 2006-05-01 15:38:15.000000000 +0900 @@ -265,9 +265,17 @@ (define-enum-conditionally SO_TYPE) (define-enum-conditionally SO_BROADCAST) (define-enum-conditionally SO_SNDBUF) -(define-enum-conditionally SO_RFCBUF) +(define-enum-conditionally SO_RCVBUF) (define-enum-conditionally SO_PRIORITY) (define-enum-conditionally SO_ERROR) +(define-enum-conditionally SO_DEBUG) +(define-enum-conditionally SO_DONTROUTE) +(define-enum-conditionally SO_LINGER) +(define-enum-conditionally SO_RCVLOWAT) +(define-enum-conditionally SO_SNDLOWAT) +(define-enum-conditionally SO_RCVTIMEO) +(define-enum-conditionally SO_SNDTIMEO) +(define-enum-conditionally SO_REUSEPORT) (define-enum-conditionally SOL_TCP) (define-enum-conditionally TCP_NODELAY) diff -ru Gauche-0.8.7.orig/ext/net/net.scm Gauche-0.8.7/ext/net/net.scm --- Gauche-0.8.7.orig/ext/net/net.scm 2006-05-01 15:35:58.000000000 +0900 +++ Gauche-0.8.7/ext/net/net.scm 2006-05-01 15:40:11.000000000 +0900 @@ -62,6 +62,8 @@ |IPPROTO_IP| |IPPROTO_ICMP| |IPPROTO_TCP| |IPPROTO_UDP| |IPPROTO_IPV6| |SOL_SOCKET| |SO_KEEPALIVE| |SO_OOBINLINE| |SO_REUSEADDR| |SO_TYPE| |SO_BROADCAST| |SO_SNDBUF| |SO_RCVBUF| |SO_PRIORITY| |SO_ERROR| |SOMAXCONN| + |SO_DEBUG| |SO_DONTROUTE| |SO_LINGER| |SO_RCVLOWAT| |SO_SNDLOWAT| + |SO_RCVTIMEO| |SO_SNDTIMEO| |SO_REUSEPORT| |SOL_TCP| |TCP_NODELAY| |TCP_MAXSEG| |TCP_CORK| |SOL_IP| |IP_OPTIONS| |MSG_CTRUNC| |MSG_DONTROUTE| |MSG_EOR| |MSG_OOB| |MSG_PEEK|
2006/04/25 23:25:35 PDT: radix が 10 未満のときの digit->integer の挙動が変だと思います。
gosh> (digit->integer #\1 2) 1 gosh> (digit->integer #\2 2) 2 gosh> (digit->integer #\3 2) #f gosh> (digit->integer #\8 8) 8 gosh> (digit->integer #\9 8) #f gosh> (digit->integer #\a 10) #f
(digit->integer #\2 2) 等は #f になるべきではないでしょうか。
--- char.c.orig 2006-04-26 15:14:59.000000000 +0900
+++ char.c 2006-04-26 15:16:22.000000000 +0900
@@ -83,7 +83,7 @@
{
if (ch < '0') return -1;
if (radix <= 10) {
- if (ch <= '0' + radix) return (ch - '0');
+ if (ch < '0' + radix) return (ch - '0');
} else {
if (ch <= '9') return (ch - '0');
if (ch < 'A') return -1;
2006/04/19 03:01:46 PDT: 次のようなマクロを展開しようとすると無限ループになります。
gosh> (define-syntax let
(syntax-rules ()
((_ rest ...)
((with-module null let) rest ...))))
gosh> (let () 1)
^C
*** ERROR: Compile Error: unhandled signal 2 (SIGINT)
"(stdin)":15:(let () 1)
Stack Trace:
_______________________________________
マクロ展開中の with-module の処理に問題があるみたいです。
gosh> (define pi 3) pi gosh> pi 3 gosh> (require "math/const") #<undef> gosh> (with-module math.const pi) 3.141592653589793 gosh> (define-syntax bar (syntax-rules () ((_) (with-module math.const pi)))) #<undef> gosh> (bar) 3
jingu 2006/04/09 01:14:22 PDT: IPv6の場合、socket-recvfromが送信者のソケットアドレスを
正しく返しませんでした。
--- net.c.orig 2006-04-09 16:13:38.000000000 +0900
+++ net.c 2006-04-09 17:33:17.000000000 +0900
@@ -360,18 +360,19 @@
{
int r;
char *buf;
- struct sockaddr from;
- socklen_t fromlen = sizeof(from);
+ const char from[SCM_SOCKADDR_MAXLEN];
+ socklen_t fromlen = SCM_SOCKADDR_MAXLEN;
+
if (SOCKET_CLOSED(sock->fd)) {
Scm_Error("attempt to recv from a closed socket: %S", sock);
}
buf = SCM_NEW_ATOMIC2(char*, bytes);
- SCM_SYSCALL(r, recvfrom(sock->fd, buf, bytes, flags, &from, &fromlen));
+ SCM_SYSCALL(r, recvfrom(sock->fd, buf, bytes, flags, (struct sockaddr *)&from, &fromlen));
if (r < 0) {
Scm_SysError("recvfrom(2) failed");
}
return Scm_Values2(Scm_MakeString(buf, r, r, SCM_MAKSTR_INCOMPLETE),
- Scm_MakeSockAddr(NULL, &from, fromlen));
+ Scm_MakeSockAddr(NULL, (struct sockaddr *)&from, fromlen));
}
/* Low-level setsockopt() and getsockopt() interface. */
Index: ext/net/addr.c
===================================================================
RCS file: /cvsroot/gauche/Gauche/ext/net/addr.c,v
retrieving revision 1.23
diff -u -r1.23 addr.c
--- ext/net/addr.c 22 Jan 2006 00:52:54 -0000 1.23
+++ ext/net/addr.c 12 Apr 2006 01:43:07 -0000
@@ -77,9 +77,10 @@
/* creates sockaddr from struct sockaddr. */
ScmObj Scm_MakeSockAddr(ScmClass *klass, struct sockaddr *saddr, int len)
{
- ScmSockAddr *addr;
- addr = SCM_NEW2(ScmSockAddr*,
- sizeof(ScmSockAddr) - sizeof(struct sockaddr) + len);
+ ScmSockAddrStorage *addr;
+ SCM_ASSERT(sizeof(scm_sockaddr_storage) >= len);
+ SCM_ASSERT(saddr != NULL);
+ addr = SCM_NEW(ScmSockAddrStorage);
if (klass == NULL) {
switch (saddr->sa_family) {
case AF_UNIX:
@@ -100,7 +101,9 @@
}
SCM_SET_CLASS(addr, klass);
addr->addrlen = len;
- memset(&addr->addr, 0, len);
+#ifdef HAVE_SS_LEN
+ addr->addr.ss_len = len;
+#endif
memcpy(&addr->addr, saddr, len);
return SCM_OBJ(addr);
}
@@ -109,7 +112,6 @@
* Unix domain socket
*/
-#define UNIX_ADDRESS_PATH_MAX 108
static ScmObj sockaddr_un_allocate(ScmClass *klass, ScmObj initargs);
SCM_DEFINE_BUILTIN_CLASS(Scm_SockAddrUnClass, sockaddr_print,
@@ -124,14 +126,17 @@
Scm_Error(":path parameter must be a string, but got %S", path);
}
addr = SCM_NEW(ScmSockAddrUn);
- SCM_SET_CLASS(addr, &Scm_SockAddrUnClass);
+ SCM_SET_CLASS(addr, SCM_CLASS_SOCKADDR_UN);
memset(&addr->addr, 0, sizeof(struct sockaddr_un));
+#ifdef HAVE_SUN_LEN
+ addr->addr.sun_len = sizeof(struct sockaddr_un);
+#endif
addr->addr.sun_family = AF_UNIX;
if (SCM_STRINGP(path)) {
u_int size;
const char *cpath = Scm_GetStringContent(SCM_STRING(path), &size,
NULL, NULL);
- if (size >= UNIX_ADDRESS_PATH_MAX-1) {
+ if (size >= sizeof(addr->addr.sun_path)-1) {
Scm_Error("path too long: %S", path);
}
memcpy(addr->addr.sun_path, cpath, size);
@@ -161,7 +166,7 @@
port);
}
addr = SCM_NEW(ScmSockAddrIn);
- SCM_SET_CLASS(addr, &Scm_SockAddrInClass);
+ SCM_SET_CLASS(addr, SCM_CLASS_SOCKADDR_IN);
memset(&addr->addr, 0, sizeof(struct sockaddr_in));
#ifdef HAVE_SIN_LEN
addr->addr.sin_len = sizeof(struct sockaddr_in);
@@ -222,7 +227,7 @@
port);
}
addr = SCM_NEW(ScmSockAddrIn6);
- SCM_SET_CLASS(addr, &Scm_SockAddrIn6Class);
+ SCM_SET_CLASS(addr, SCM_CLASS_SOCKADDR_IN6);
memset(&addr->addr, 0, sizeof(struct sockaddr_in6));
#ifdef HAVE_SIN6_LEN
addr->addr.sin6_len = sizeof(struct sockaddr_in6);
Index: ext/net/net.ac
===================================================================
RCS file: /cvsroot/gauche/Gauche/ext/net/net.ac,v
retrieving revision 1.4
diff -u -r1.4 net.ac
--- ext/net/net.ac 15 Jul 2004 07:10:05 -0000 1.4
+++ ext/net/net.ac 12 Apr 2006 01:43:07 -0000
@@ -37,11 +37,57 @@
fi
dnl
+dnl Check availability of struct sockaddr_storage
+dnl
+AC_CACHE_CHECK(struct sockaddr_storage is available, ac_cv_struct_sockaddr_storage, [
+AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <sys/socket.h>
+], [
+struct sockaddr_storage ss;
+], ac_cv_struct_sockaddr_storage=yes, ac_cv_struct_sockaddr_storage=no)])
+
+if test "$ac_cv_struct_sockaddr_storage" = yes; then
+AC_DEFINE(HAVE_SOCKADDR_STORAGE,1,[Define if struct sockaddr_storage is available])
+fi
+
+dnl
dnl Checks if sockaddr_in and sockaddr_in6 has *_len field
dnl
+if test "$ac_cv_struct_sockaddr_storage" = yes; then
+AC_CACHE_CHECK(struct sockaddr_storage has ss_len, ac_cv_struct_sockaddr_storage_len, [
+AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <sys/socket.h>
+], [
+struct sockaddr_storage ss;
+int z = ss.ss_len;
+], ac_cv_struct_sockaddr_storage_len=yes, ac_cv_struct_sockaddr_storage_len=no)])
+
+if test "$ac_cv_struct_sockaddr_storage_len" = yes; then
+AC_DEFINE(HAVE_SS_LEN,1,[Define if struct sockaddr_storage has ss_len])
+fi
+fi
+
+AC_CACHE_CHECK(struct sockaddr_un has sun_len, ac_cv_struct_sockaddr_un_len, [
+AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <sys/un.h>
+], [
+struct sockaddr_un addr;
+int z = addr.sun_len;
+], ac_cv_struct_sockaddr_un_len=yes, ac_cv_struct_sockaddr_un_len=no)])
+
+if test "$ac_cv_struct_sockaddr_un_len" = yes; then
+AC_DEFINE(HAVE_SUN_LEN,1,[Define if struct sockaddr_un has sun_len])
+fi
+
AC_CACHE_CHECK(struct sockaddr_in has sin_len, ac_cv_struct_sockaddr_in_len, [
-AC_TRY_COMPILE([#include <netinet/in.h>], [
+AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <netinet/in.h>
+], [
struct sockaddr_in addr;
int z = addr.sin_len;
], ac_cv_struct_sockaddr_in_len=yes, ac_cv_struct_sockaddr_in_len=no)])
@@ -52,7 +98,10 @@
if test "$ac_cv_ipv6" = yes; then
AC_CACHE_CHECK(struct sockaddr_in6 has sin6_len, ac_cv_struct_sockaddr_in6_len, [
-AC_TRY_COMPILE([#include <netinet/in.h>], [
+AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <netinet/in.h>
+], [
struct sockaddr_in6 addr;
int z = addr.sin6_len;
], ac_cv_struct_sockaddr_in6_len=yes, ac_cv_struct_sockaddr_in6_len=no)])
Index: ext/net/net.c
===================================================================
RCS file: /cvsroot/gauche/Gauche/ext/net/net.c,v
retrieving revision 1.42
diff -u -r1.42 net.c
--- ext/net/net.c 7 Jan 2006 05:54:20 -0000 1.42
+++ ext/net/net.c 12 Apr 2006 01:43:07 -0000
@@ -244,16 +244,16 @@
ScmObj Scm_SocketAccept(ScmSocket *sock)
{
- const char addrbuf[SCM_SOCKADDR_MAXLEN];
+ scm_sockaddr_storage addrbuf;
int newfd;
- socklen_t addrlen = SCM_SOCKADDR_MAXLEN;
+ socklen_t addrlen = sizeof(addrbuf);
ScmSocket *newsock;
ScmClass *addrClass = Scm_ClassOf(SCM_OBJ(sock->address));
if (SOCKET_CLOSED(sock->fd)) {
Scm_Error("attempt to accept a closed socket: %S", sock);
}
- SCM_SYSCALL(newfd, accept(sock->fd, (struct sockaddr *)addrbuf, &addrlen));
+ SCM_SYSCALL(newfd, accept(sock->fd, (struct sockaddr*)&addrbuf, &addrlen));
if (SOCKET_INVALID(newfd)) {
if (errno == EAGAIN) {
return SCM_FALSE;
@@ -264,7 +264,7 @@
newsock = make_socket(newfd, sock->type);
newsock->address =
SCM_SOCKADDR(Scm_MakeSockAddr(addrClass,
- (struct sockaddr *)addrbuf,
+ (struct sockaddr*)&addrbuf,
addrlen));
newsock->status = SCM_SOCKET_STATUS_CONNECTED;
return SCM_OBJ(newsock);
@@ -287,34 +287,34 @@
ScmObj Scm_SocketGetSockName(ScmSocket *sock)
{
- const char addrbuf[SCM_SOCKADDR_MAXLEN];
+ scm_sockaddr_storage addrbuf;
int r;
- socklen_t addrlen = SCM_SOCKADDR_MAXLEN;
+ socklen_t addrlen = sizeof(addrbuf);
if (SOCKET_CLOSED(sock->fd)) {
Scm_Error("attempt to get the name of a closed socket: %S", sock);
}
- SCM_SYSCALL(r, getsockname(sock->fd, (struct sockaddr *)addrbuf, &addrlen));
+ SCM_SYSCALL(r, getsockname(sock->fd, (struct sockaddr*)&addrbuf, &addrlen));
if (r < 0) {
Scm_SysError("getsockname(2) failed");
}
- return SCM_OBJ(Scm_MakeSockAddr(NULL, (struct sockaddr *)addrbuf, addrlen));
+ return SCM_OBJ(Scm_MakeSockAddr(NULL, (struct sockaddr*)&addrbuf, addrlen));
}
ScmObj Scm_SocketGetPeerName(ScmSocket *sock)
{
- const char addrbuf[SCM_SOCKADDR_MAXLEN];
+ scm_sockaddr_storage addrbuf;
int r;
- socklen_t addrlen = SCM_SOCKADDR_MAXLEN;
+ socklen_t addrlen = sizeof(addrbuf);
if (SOCKET_CLOSED(sock->fd)) {
Scm_Error("attempt to get the name of a closed socket: %S", sock);
}
- SCM_SYSCALL(r, getpeername(sock->fd, (struct sockaddr *)addrbuf, &addrlen));
+ SCM_SYSCALL(r, getpeername(sock->fd, (struct sockaddr*)&addrbuf, &addrlen));
if (r < 0) {
Scm_SysError("getpeername(2) failed");
}
- return SCM_OBJ(Scm_MakeSockAddr(NULL, (struct sockaddr *)addrbuf, addrlen));
+ return SCM_OBJ(Scm_MakeSockAddr(NULL, (struct sockaddr*)&addrbuf, addrlen));
}
ScmObj Scm_SocketSend(ScmSocket *sock, ScmString *msg, int flags)
@@ -368,18 +368,18 @@
{
int r;
char *buf;
- struct sockaddr from;
+ scm_sockaddr_storage from;
socklen_t fromlen = sizeof(from);
if (SOCKET_CLOSED(sock->fd)) {
Scm_Error("attempt to recv from a closed socket: %S", sock);
}
buf = SCM_NEW_ATOMIC2(char*, bytes);
- SCM_SYSCALL(r, recvfrom(sock->fd, buf, bytes, flags, &from, &fromlen));
+ SCM_SYSCALL(r, recvfrom(sock->fd, buf, bytes, flags, (struct sockaddr*)&from, &fromlen));
if (r < 0) {
Scm_SysError("recvfrom(2) failed");
}
return Scm_Values2(Scm_MakeString(buf, r, r, SCM_MAKSTR_INCOMPLETE),
- Scm_MakeSockAddr(NULL, &from, fromlen));
+ Scm_MakeSockAddr(NULL, (struct sockaddr*)&from, fromlen));
}
/* Low-level setsockopt() and getsockopt() interface. */
Index: ext/net/gauche/net.h
===================================================================
RCS file: /cvsroot/gauche/Gauche/ext/net/gauche/net.h,v
retrieving revision 1.2
diff -u -r1.2 net.h
--- ext/net/gauche/net.h 4 Sep 2005 23:59:54 -0000 1.2
+++ ext/net/gauche/net.h 12 Apr 2006 01:43:07 -0000
@@ -75,6 +75,20 @@
* Socket address
*/
+#ifdef HAVE_SOCKADDR_STORAGE
+typedef struct sockaddr_storage scm_sockaddr_storage;
+#else
+#define SCM_SOCKADDR_MAXLEN 128
+typedef char scm_sockaddr_storage[SCM_SOCKADDR_MAXLEN];
+#endif
+
+/* Real Socket Address Storage. */
+typedef struct ScmSockAddrStorageRec {
+ SCM_HEADER;
+ socklen_t addrlen;
+ scm_sockaddr_storage addr;
+} ScmSockAddrStorage;
+
typedef struct ScmSockAddrRec {
SCM_HEADER;
socklen_t addrlen;
@@ -129,8 +143,6 @@
#endif /* HAVE_IPV6 */
-#define SCM_SOCKADDR_MAXLEN 128
-
/*------------------------------------------------------------------
* Socket
*/
Index: src/gauche/config.h.in
===================================================================
RCS file: /cvsroot/gauche/Gauche/src/gauche/config.h.in,v
retrieving revision 1.49
diff -u -r1.49 config.h.in
--- src/gauche/config.h.in 4 Mar 2006 09:17:31 -0000 1.49
+++ src/gauche/config.h.in 12 Apr 2006 01:43:07 -0000
@@ -194,6 +194,15 @@
/* Define if struct sockaddr_in has sin_len */
#undef HAVE_SIN_LEN
+/* Define if struct sockaddr_un has sun_len */
+#undef HAVE_SUN_LEN
+
+/* Define if struct sockaddr_storage is available */
+#undef HAVE_SOCKADDR_STORAGE
+
+/* Define if struct sockaddr_storage has ss_len */
+#undef HAVE_SS_LEN
+
/* Define to 1 if you have the `srand48' function. */
#undef HAVE_SRAND48
[Ruby 1.8.4 ext/socket/socket.c]
#ifndef HAVE_SOCKADDR_STORAGE
/*
* RFC 2553: protocol-independent placeholder for socket addresses
*/
#define _SS_MAXSIZE 128
#define _SS_ALIGNSIZE (sizeof(double))
#define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof(unsigned char) * 2)
#define _SS_PAD2SIZE (_SS_MAXSIZE - sizeof(unsigned char) * 2 - \
_SS_PAD1SIZE - _SS_ALIGNSIZE)
struct sockaddr_storage {
#ifdef HAVE_SA_LEN
unsigned char ss_len; /* address length */
unsigned char ss_family; /* address family */
#else
unsigned short ss_family;
#endif
char __ss_pad1[_SS_PAD1SIZE];
double __ss_align; /* force desired structure storage alignment */
char __ss_pad2[_SS_PAD2SIZE];
};
#endif
Index: ext/net/net.ac =================================================================== RCS file: /cvsroot/gauche/Gauche/ext/net/net.ac,v retrieving revision 1.5 diff -u -r1.5 net.ac --- ext/net/net.ac 5 Jul 2006 03:35:54 -0000 1.5 +++ ext/net/net.ac 5 Jul 2006 07:44:17 -0000 @@ -39,7 +39,7 @@ dnl dnl Check to see if the system provides sockaddr_storage dnl -AC_CHECK_TYPES([struct sockaddr_storage],,,[#include <netinet/in.h>]) +AC_CHECK_TYPES([struct sockaddr_storage],,,[#include <sys/socket.h>]) dnl dnl Checks if sockaddr_in and sockaddr_in6 has *_len field