NSPipeの最大数?

62 views
Skip to first unread message

おおもり

unread,
Sep 27, 2007, 4:30:36 AM9/27/07
to cocoa-dev-japan
下記コードでvfdecryptというコマンドラインツールに作業をさせて結果をもらうというようにしようとしています。(力技での暗号化.dmgファ
イルの解読です。)

ところが、127回ループを繰り返したところで標準出力先のNSPipeが出来なくなります。(Descriptionでnullが返って来る)


NSPipeは一定時間内に127個までとか制限があるのでしょうか?

制限があるとしたら何か回避策はありますでしょうか?


実行結果のLog
task[16703] Error 22
task[16703] vfdecrypt -i 022-3601-4.dmg -o decrypted.dmg -k fx
task[16703] ********************** 5 23 <NSConcretePipe: 0x15b39260>
task[16703] Error 23
task[16703] vfdecrypt -i 022-3601-4.dmg -o decrypted.dmg -k fy
task[16703] ********************** 5 24 (null)
task[16703] *** -[NSCFDictionary setObject:forKey:]: attempt to
insert nil value


コード。単にボタンを押したらmyAction:が呼ばれるようになっている。
--------------------------------------------------------------------------------------------------------------------
#import "MyObject.h"

@implementation MyObject

- (IBAction)myAction:(id)sender
{
NSString *baseString = [NSString
stringWithString:@"abcdefghijklmnopqrstuvwxyz"];
int baseStringLength = [baseString length];


int i[baseStringLength];

for ( i[1] = 1 ; i[1] < baseStringLength ; i[1]++){
for ( i[0] = 1 ; i[0] < baseStringLength ; i[0]++){

NSTask *task = [[NSTask alloc] init];
NSPipe *pError = [NSPipe pipe];//エラー出力先
NSPipe *pOutput = [NSPipe pipe];//標準出力先
[task retain];
[pOutput retain];
[pError retain];


[task setLaunchPath:@"/Users/oomori/Desktop/
iPod1,1_1.1_3A101a_Restore.ipsw/vfdecrypt"];


[task setCurrentDirectoryPath:@"/Users/oomori/Desktop/
iPod1,1_1.1_3A101a_Restore.ipsw"];


NSString *commandString = [NSString stringWithFormat:@"vfdecrypt -
i 022-3601-4.dmg -o decrypted.dmg -k %@%@"
,[baseString substringWithRange:NSMakeRange(i[1],1)]
,[baseString substringWithRange:NSMakeRange(i[0],1)]
];
NSLog(commandString);
[task setArguments:[NSArray arrayWithObjects:commandString,nil]];
NSLog(@"********************** %d %d %@",i[1],i[0],[pOutput
description]);

[task setStandardOutput:pOutput];


//エラー出力先
[task setStandardError : pError];
//実行
[task launch];
//終了まで待つ
[task waitUntilExit];


NSData *dataError = [[pError fileHandleForReading]
availableData];
NSData *dataOutput = [[pOutput fileHandleForReading]
availableData];


//NSLog([NSString stringWithFormat:@"%s",[dataError bytes]]);

if ([[NSString stringWithFormat:@"%s",[dataError bytes]]
compare:@"No " options:NSCaseInsensitiveSearch range:NSMakeRange(0,3)]
== NSOrderedSame){
NSLog(@"Error %d",i[0]);
}else{
NSLog(@"OK");
NSLog([[[NSString alloc] initWithData:dataOutput
encoding:NSShiftJISStringEncoding] autorelease]);
}


}//[0]
}//[1]


}

@end
--------------------------------------------------------------------------------------------------------------------

Masanori Yanagawa

unread,
Sep 27, 2007, 5:07:54 AM9/27/07
to cocoa-d...@googlegroups.com
梁川@ビー・ユー・ジー です。

On 2007/09/27, at 17:30, おおもり wrote:
> ところが、127回ループを繰り返したところで標準出力先の
> NSPipeが出来なくなります。(Descriptionでnullが
> 返って来る)
>
>
> NSPipeは一定時間内に127個までとか制限があるのでしょうか?

NSPipeをreleaseしていない = pipeがクローズされていな
いため、プロセス当たりのファイルディスクリプタ数の制限 (通
常256) に引っ掛かっているのではないでしょうか。

# ループ1回にpipe二つなので約半分

--
ya...@bug.co.jp
梁川 雅典 (株)ビー・ユー・ジー


大森 智史

unread,
Sep 27, 2007, 5:30:29 AM9/27/07
to cocoa-d...@googlegroups.com
大森です。

ありがとうございます。

プロセス当たりのファイルディスクリプタ数の制限があるのですか。
それに引っかかってそうですね。

releaseしてみましたがダメでした。
他に方法考えてみます。


> 梁川@ビー・ユー・ジー です。


>>
>> NSPipeは一定時間内に127個までとか制限があるのでしょうか?
>
> NSPipeをreleaseしていない = pipeがクローズされていな
> いため、プロセス当たりのファイルディスクリプタ数の制限 (通
> 常256) に引っ掛かっているのではないでしょうか。
>
> # ループ1回にpipe二つなので約半分

------------------------------------------------------------------------
--------------------------


}else{
NSLog(@"OK");
NSLog([[[NSString alloc] initWithData:dataOutput
encoding:NSShiftJISStringEncoding] autorelease]);
}

[pOutput release];
[pError release];
[task release];

Masanori Yanagawa

unread,
Sep 27, 2007, 6:04:03 AM9/27/07
to cocoa-d...@googlegroups.com
梁川@ビー・ユー・ジー です。

On 2007/09/27, at 18:30, 大森 智史 wrote:
> プロセス当たりのファイルディスクリプタ数の制限があるのですか。
> それに引っかかってそうですね。
>
> releaseしてみましたがダメでした。

簡単に「NSPipeをreleaseしていない」と書いてしまいま
したが、ただ [pError release] (など) を一つ足せばい
いというのではなくて、

> NSPipe *pError = [NSPipe pipe];

ということはautorelease poolにもretainされているだろ
うし、NSTaskに渡していることでもretainされているかも
しれません (されてないかもしれませんが)。

要するに、NSPipeがdeallocされるように全体の辻褄が
合っていないとダメだろう、ということで。

大森 智史

unread,
Sep 27, 2007, 8:22:57 AM9/27/07
to cocoa-d...@googlegroups.com
大森です。


> 簡単に「NSPipeをreleaseしていない」と書いてしまいま
> したが、ただ [pError release] (など) を一つ足せばい
> いというのではなくて、
>
>> NSPipe *pError = [NSPipe pipe];

ああ、なるほど。
retain count 見てみます。

ありがとうございます。

おおもり

unread,
Sep 27, 2007, 7:28:21 PM9/27/07
to cocoa-dev-japan

> 要するに、NSPipeがdeallocされるように全体の辻褄が
> 合っていないとダメだろう、ということで。

ご指摘どおり
参照カウントを一つ減らしてからreleaseしたらいけるようになりました。

ありがとうございました。

NSPipe * pOutput = [[NSPipe alloc] init];

NSDecrementExtraRefCountWasZero(pOutput);

[pOutput release];

慧 松本

unread,
Oct 1, 2007, 11:01:55 PM10/1/07
to cocoa-dev-japan
松本です。

キーボードの入力モードが、現在カナモードか、ローマ字入力モードかを
プログラム内部から検出するにはどのようにしたらいいのでしょうか?

Cocoaとは直接関係ないかも知れませんが、どなたか教えてもらえると
うれしいです。m(_._)m

-----------------------------------------------------
Satoshi Matsumoto <sat...@mac.com>
816-5 Odake, Odawara, Kanagawa, Japan 256-0802


慧 松本

unread,
Oct 4, 2007, 7:04:12 AM10/4/07
to cocoa-d...@googlegroups.com
松本です。

On 2007/10/02, at 12:01, 慧 松本 wrote:
> キーボードの入力モードが、現在カナモードか、ローマ字入力モード
> かを
> プログラム内部から検出するにはどのようにしたらいいのでしょうか?

解決しました。(^^;

-------
long keyScript;
keyScript = GetScriptManagerVariable( smKeyScript );

keyScript に
0 (smRoman) が返されれば、ローマ字入力モード。
1 (smJapanese) が返されればカナ入力モード。

詳しくは...
http://developer.apple.com/documentation/Carbon/Reference/
Script_Manager/Reference/reference.html

慧 松本

unread,
Nov 1, 2007, 9:26:02 PM11/1/07
to cocoa-d...@googlegroups.com
松本です。

わたしもLeopardねたを1つ。。。。(^^;

Leopardの NSString の以下のようなメッソッドでテキストエン
コーディングを指定して保存すると、

writeToFile:atomically:encoding:error:

テキストエンコーディングが拡張ファイルアトリビュートに自動的に書
き込まれるようになりました。

試しに、Leopard のTextEditで何かの書類を、
ISO-2022JPで保存して、 その拡張ファイルアトリビュートを、
xattrコマンドでみてみると

$ xattr -l /Users/satoshi/Desktop/test.txt
com.apple.FinderInfo:
0000 00 00 00 00 00 00 00 00 00 10 00 00 00 00 00
00 ................
0010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 ................

com.apple.TextEncoding: ISO-2022-JP;2080

とのように、項目「com.apple.TextEncoding」にテキストエン
コーディングが書き込まれているのがわかります。

このファイルをTextEditで開くと、以下のメソッドでエンコー
ディングが自動判定され、

initWithContentsOfFile:usedEncoding:error:

usedEncodingに ISO-2022JP がセットされ正しく開かれます。

ーーーーーーーーーーーーーーーー

日本語エンコーディングの場合は、ファイルの内容からエンコーディン
グをある程度判定することができますが、ラテン系言語のエンコーディ
ングは、ファイルの内容から判定することはまず不可能で、上記のよう
な拡張ファイルアトリビュートの仕組みが必要です。

ただ、Cocoa以外のアプリケーションで保存されていたり、また
NSDataのメソッドで保存されたファイルには、テキストエンコーディン
グは拡張ファイルアトリビュートには書き込まれないので、従来通り
(Tigerと同じ)の動作になります。

Reply all
Reply to author
Forward
0 new messages