MOSA Multi-OS Software Artists

MOSAはソフトウェア開発者を支援します

  • iPhone/iPod touch アプリ紹介
  • MOSA掲示板
  • 活動履歴
  • About MOSA(English)

MOSA Developer News[MOSADeN=モサ伝]第250号

2007-05-08 

目次

  • 「「Wonderful Server Life」    第46回    田畑 英和
  • 小池邦人の「Carbon API 徒然草」
  • ターミナルの向こうから      第1回  海上 忍 ★新連載★
  • 書籍紹介             GDBデバッギング入門

「Wonderful Server Life」  第46回  田畑 英和

  〜アカウント編〜

 Leopardのリリースが10月に延期になりました。ホッとしている方もいればガッカリしている方もいらっしゃるかと思います。サーバの場合は、頻繁にOSをアップデートできなかったりもしますので、準備する期間が増えたのではないかと思います。これまでのメジャーバージョンアップでは、アップデート後は旧バージョンのOSは販売されなくなりましたので、10月以降に構築を開始するシステムでは、Leopardベースでのシステム構築になるかと思われます。
 また、4月中旬に開催されたNABでは「Final Cut Studio 2」が発表されました。これと同時にサーバアプリケーションの「Final Cut Server」も発表されています。クライアントアプリケーションだけではなく、サーバアプリケーションも充実していく傾向にあります。

・Final Cut Server
http://www.apple.com/jp/finalcutserver/

◇コンピュータアカウント
 これまで、ユーザおよびグループのアカウント管理について説明してきました。アカウント管理の締めくくりとしてコンピュータアカウントについて説明していきます。
 ユーザやグループは、ファイルシステムのアクセス権を管理するときに使用しますので比較的なじみのあるタイプのアカウントかと思いますが、Mac OS XServerでは、コンピュータもアカウントとして管理できます。
 コンピュータアカウントを使ってなにができるかですが、次のようなことが実現できます。

・コンピュータ単位での環境設定の管理
・コンピュータごとのアクセス制御
・ネットワーク表示のカスタマイズ

 サーバ上で一元管理する環境設定には、コンピュータアカウントでのみ有効な設定項目も用意されています。
 コンピュータアカウントですが、1台1台のコンピュータを個別に管理するのではなく、1台以上のコンピュータをリストとして管理するようになっています。例えば機種別にコンピュータリストを作成したり、設置場所ごとにコンピュータリストを作成するなどの応用が可能になります。

◇標準のコンピュータアカウント
 システムをセットアップした時点で、自動的に次の3つのコンピュータリストが作成されています。

・ゲストコンピュータ
・Windowsコンピュータ
・すべてのコンピュータ

 まず「ゲストコンピュータ」ですが、どのリストにも含まれないコンピュータが存在した場合、自動的にゲストコンピュータとして扱われます。「ゲストコンピュータ」に手動でコンピュータを登録することはできません。
 なんらかのコンピュータリストにコンピュータを追加すれば、自動的に「すべてのコンピュータ」にも登録されます。つまり、「すべてのコンピュータ」のリストを参照すれば、登録済みコンピュータの一覧を確認することができます。「すべてのコンピュータ」に直接コンピュータを登録することもできます。
 また、これらのコンピュータリストを削除することはできません。

・ゲストコンピュータ
http://homepage.mac.com/htabata/MXS10.3/img/WGM_Computer/WGM_Computer_01.png

◇コンピュータリストの設定方法
 コンピュータリストの作成は、グループの作成手順と似ています。「ワークグループマネージャ」を起動し、ツールバーから「アカウント」をクリックして、画面に左側にコンピュータリストの一覧を表示します。
 次にツールバーから「新規コンピュータリスト」をクリックし、名前を付けて保存します。
 これでコンピュータリストが作成できましたので、あとは任意のコンピュータをリストのメンバーとして登録していきます。コンピュータの登録方法ですが、メンバーリストの下にある「+」ボタンをクリックし、ここでコンピュータの「名前」と「Ethernet ID」(MACアドレス)を入力します。

・コンピュータの登録(その1)
http://homepage.mac.com/htabata/MXS10.3/img/WGM_Computer/WGM_Computer_04.png

 あるいは、「…」ボタンをクリックするとネットワーク上のコンピュータをブラウズすることができますので、ここから任意のコンピュータを選択して自動的に登録することもできます。コンピュータをブラウズするには、対象となるコンピュータがネットワークに接続され、電源がOnになっている必要があります。
 手動でコンピュータを登録する場合、Ethernet IDを手入力する必要がありますが、打ち間違いを防ぐためにも自動的に登録するのがよいでしょう。

・コンピュータの登録(その2)
http://homepage.mac.com/htabata/MXS10.3/img/WGM_Computer/WGM_Computer_05.png

 コンピュータリストは、1つのリストに最大2,000台のコンピュータを登録することができます。
 グループの場合は1つのユーザを複数のグループに登録することができましたが、コンピュータリストの場合は1台のコンピュータを複数のコンピュータリストに所属させることはできません。
 それでは、次回はコンピュータリストの応用について解説します。
つづく
                               

小池邦人のCarbon API 徒然草(2007/05/04)

〜 Carbonモダンアプリケーションへの道(その15) 〜

今回からは、FSRefで参照したファイルやフォルダ(ディレクトリ)への基本的なアクセス(作成、書き込み、読み込み、削除など)について調べて行きます。まずはファイルを作成することから始めてみましょう。

Carbon Frameworkでファイルを作成する場合には、FSCreateFileUnicode()APIを利用します。このAPIを含め、ファイルアクセスに関係するAPIは、すべてヘッダーファイルのFiles.hに定義されています。

OSErr  FSCreateFileUnicode(

       const FSRef *parentRef,           // 親ディレクトリのFSRef
       UniCharCount nameLength,          // ファイル名の長さ(2バイト単位)
       const UniChar *name,              // ユニコードファイル名
       FSCatalogInfoBitmap whichInfo,    // 設定したいファイル情報を指示する
       const FSCatalogInfo *catalogInfo, // FSCatalogInfo構造体に情報を設定
       FSRef *newRef,                    // 作成されたファイルのFSRef
       FSSpec *newSpec )                 // 作成されたファイルのFSSpec

最初のparentRefでファイルを作成する親ディレクトリ(フォルダ)の場所を指示し、次のnameLengthとnameでファイル名(ユニコード)を指示します。whichInfoは、作成したファイルに対して何かしらの情報を設定したい場合のみ指定します。指示は、unsigned long値の各ビットを立てることで行います。その場合には、情報格納場所としてのcatalogInfoにFSCatalogInfo構造体の先頭アドレスをセットしておきます。もし何も情報を指定しなければ、whichInfoにはkFSCatInfoNoneをセットし、catalogInfoの方はNULLでかまいません。最後のnewRefとnewSpecには、作成されたファイルのFSRefとFSSpec構造体が代入されますが、こちらも必要がなければ、それぞれNULLを代入しておきます。

FSCreateFileUnicode()は、ファイルを作成するだけなのにやけに引数が多いですね。そこで、親ディレクトリ(FSRef)とファイル名(CFStringRef)を与えるだけの簡単なファイル作成ルーチンを別途用意してみます。ルーチン名はcreateFile()です。正しくファイルが作成できた場合には、そのファイルのFSRefを返してきます。

OSErr createFile( FSRef *pfsref,CFStringRef cfstr,FSRef *fsref )
{

   UniChar         buf[256];    // ユニコードなので一文字は2バイト
   FSRef           tfsref;
   OSErr           err=1;
   UniCharCount    len;

   if( len=(UniCharCount)CFStringGetLength( cfstr ) ) // ファイル名の長さを得る
   {
       CFStringGetCharacters( cfstr,CFRangeMake( 0,len ),buf ); // ユニコードに
       if( ! FSMakeFSRefUnicode( pfsref,len,buf,kTextEncodingUnicodeDefault,
                                                                 &tfsref ) )
           FSDeleteObject( &tfsref ); // すでに存在していたら削除
       err=FSCreateFileUnicode( pfsref,len,buf,kFSCatInfoNone,NULL,fsref,NULL);
   }                                  // ファイルを作成
   return( err );
}


CFStringRefで定義されたファイル名は、CFStringGetCharacters()を使いユニコード文字列へと変換されています。先んじてFSMakeFSRefUnicode()を呼び出しているのは、同じ名称のファイルが存在しているかどうかを確認するためです。もし同じ名称のファイル(もしくはディレクトリ)が存在していると、FSMakeFSRefUnicode()がnoErr(ゼロ)を返しますので、そのファイルをFSDeleteObject()で削除してしまいます。この削除処理に関しては、用途によっては実行せずエラーを返すだけの方が良いケースがあるとおもいますので、利用する場合には注意してください。ちなみに、削除せずFSCreateFileUnicode()を実行するとエラーが返ります。

同様な引数を与えることで、ファイルではなくディレクトリ(フォルダ)を作成する場合には、以下のFSCreateDirectoryUnicode()を利用します。FSCreateFileUnicode()より引数がひとつ多いのですが、最後の引数には作成されたディレクトリのディレクトリID番号(unsigned long値)が返ります(不必要ならNULL指定)。こちらの場合には、すでに同名ディレクトリが存在していれば削除する必要はないので、エラーを返すだけの処理となっています。

OSErr createFolderFile( FSRef *pfsref,CFStringRef cfstr,FSRef *fsref )
{

   UniChar         buf[256];    // ユニコードなので一文字は2バイト
   OSErr           err=1;
   UniCharCount    len;

   if( len=(UniCharCount)CFStringGetLength( cfstr ) )// ファイル名の長さを得る
   {
       CFStringGetCharacters( cfstr,CFRangeMake( 0,len ),buf ); // ユニコードに
       err=FSCreateDirectoryUnicode( pfsref,len,buf,kFSCatInfoNone,NULL,fsref,
                                                                  NULL,NULL );
   }                                // ディレクトリを作成
   return( err );
}


後から作成したファイルの各種情報を得たい場合にはどうしたら良いのでしょうか? 例えば、先ほど用いたFSMakeFSRefUnicode()を単独で使うことで、指定ファイルのFSRefを得るルーチンなどは簡単に作成することができます。

OSErr getFSRefFile( FSRef *pfsref,CFStringRef cfstr,FSRef *fsref )
{

   UniChar         buf[256];
   OSErr           err=1;
   UniCharCount    len;

   if( len=(UniCharCount)CFStringGetLength( cfstr ) ) // ファイル名の長さを得る
   {
      CFStringGetCharacters( cfstr,CFRangeMake( 0,len ),buf ); // ユニコードに
      err=FSMakeFSRefUnicode(pfsref,len,buf,kTextEncodingUnicodeDefault,fsref);
   }                          // そのファイルがあればFSRefを返す
   return( err );
}


もっと詳しい情報を得たい場合には、次のFSGetCatalogInfo() APIを利用します。

OSErr  FSGetCatalogInfo(

       const FSRef *ref,                 // 対象ファイルのFSRef
       FSCatalogInfoBitmap whichInfo,    // 欲しい情報を指示する
       FSCatalogInfo *catalogInfo,       // FSCatalogInfo構造体に情報が返る
       HFSUniStr255 *outName,            // 対象ファイルのファイル名
       FSSpec *fsSpec,                   // 対象ファイルのFSSpec
       FSRef *parentRef);                // 対象ファイルの親ディレクトリのFSRef


例えば、引数で対象ファイルのFSRefを渡して、そのファイルの親ディレクトリ(ファイルが入っているフォルダ)のFSRefを得たい場合には、以下のようなルーチンを用意しておくと便利です。

OSErr getParentFSRefFile( FSRef *fsref,FSRef *pfsref )
{
   short    err;

   err=FSGetCatalogInfo( fsref,kFSCatInfoNone,NULL,NULL,NULL,pfsref );
}


FSCatalogInfoBitmapを設定することで、FSCatalogInfo構造体に様々なファイル情報が書き込まれてきます。それらは、ファイル作成日時や編集日時、ファイル容量、アクセス権(パーミッション)情報からFinder情報まで多種多様です。どんな情報を得られるのかは(作成時に設定する場合も同様)、Files.hに詳しく記載されていますので参照してみてください。上記ルーチンと同様に、目的に応じた情報を得るためだけのルーチンを用意しておくと便利かもしれません。

今まで紹介してきたルーチンは、ファイル名をCFStringRef定義で渡していますが、代わりにHFSUniStr255構造体として渡したい場合もあります。Files.hには、CFStringRefをHFSUniStr255構造体に変換(もしくはその逆を)するためのAPIが用意されていますので、それを使えばファイル名を好みの文字列フォーマットで指示できます。HFSUniStr255構造体からCFStringRefを得るにはFSCreateStringFromHFSUniStr()を、また逆の処理にはFSGetHFSUniStrFromString()を使います。

CFStringRef FSCreateStringFromHFSUniStr( CFAllocatorRef alloc,const
                                                        HFSUniStr255 *uniStr);

OSStatus FSGetHFSUniStrFromString( CFStringRef theString,HFSUniStr255 *uniStr);


一番最初のcreateFolderFile()をFSGetHFSUniStrFromString()を使うように書き直すと、以下のようになります。

OSErr createFile( FSRef *pfsref,CFStringRef cfstr,FSRef *fsref )
{
   FSRef           tfsref;
   OSErr           err=1;
   HFSUniStr255    ustr;

   if( ! FSGetHFSUniStrFromString( cfstr,&ustr ) )
   {
      if( ustr.length ) // 文字列の長さはHFSUniStr255構造体のメンバ
      {
         CFStringGetCharacters( cfstr,CFRangeMake( 0,len ),buf );
         if( ! FSMakeFSRefUnicode( pfsref,ustr.length,(UniChar *)ustr.unicode,
                                      kTextEncodingUnicodeDefault,&tfsref ) )
             FSDeleteObject( &tfsref );
         err=FSCreateFileUnicode( pfsref,ustr.length,(UniChar *)ustr.unicode,
                                             kFSCatInfoNone,NULL,fsref,NULL );
      }
   }
   return( err );
}


次回は、ファイルのオープン(Open)とクローズ(Close)ファイルへのデータ書き込み(Write)とファイルからの読み込み(Read)、ファイルの削除(Delete)やファイル名の変更(Rename)など、一般的なファイル処理を調べてみる予定です。
つづく                                

ターミナルの向こうから      第1回  海上 忍

 〜私のMacの使い方と3つの処方箋〜

 皆さん、はじめまして。湘南セミナーにご出席の皆さんはお久しぶりです。このたび御指名により、モサ伝の連載という大役を仰せつかり、恐縮している次第です。私ごときの話で皆さんにご満足いただけるか自信はありませんが、ターミナル/UNIXコマンド関連トピックのなかでも開発に役立つものを選び、できるだけ噛み砕いた解説をさせていただこうと思います。

・私の”Macの使い方”
 初回ということで、私の”Macの使い方”から話を始めさせていただきます。旧Mac OSの時代からMacをメインにお使いの方からすると、奇異な印象を受けるかもしれませんが、NeXTSTEPなどのUNIX系OSに慣れ親しんだ人間にはそれほど珍しいことではないと思います。
 まず、デスクトップには「ターミナル」、もしくはEmacs(Carbon Emacs)が必ず1つ起動しています。ファイル操作にはそのいずれかを利用することが多く、ファインダはそれほど使いません。ファインダでブラウジングするより、シェルの入力補完機能を利用してパスを指定したほうが迅速に作業できますし、Macには「open」という便利なコマンドがあります。ファイルの削除や圧縮にはEmacsの「Dired」機能を利用するので、原稿の画面から視線を移さずに目的を果たせます。
 きちんとレイアウトした文書をつくるときには、もっぱらTeX/LaTeXを使います。EmacsでLaTeXの文書を書き、LaTeX(日本語文書ですから正確にはpLaTeX2e)でタイプセットを実行、dvipdfmxを利用してdviファイルからPDFファイルを生成、という流れです。宛名印刷のような作業には、LaTeXで記述した雛形にPerlで住所氏名を流し込む方法で対処しています。
 システムやアプリケーションの内部を”探る”ときには、コマンドの力が欠かせません。バイナリがダイナミックリンクするフレームワーク/共有ライブラリを調べるときには、「otool」コマンドを利用しますし、設定ファイル(*.plist)の閲覧には「less」コマンドが必要です。上書きが禁止されたファイルも、「sudo」と「vi」コマンドを組み合わせれば自由に編集できます。
 とはいえ、WebブラウジングにはSafariやFirefoxを使いますし、メールの読み書きもApple Mailで済ませています。iTunesで音楽を聴かずに原稿を書くなど、考えられないことです。ファイルの検索も、遅い「find」コマンドではなくSpotlightを愛用しています。基本的な作業スタイルは、多くのMacユーザと変わらないと思います。
 前置きが長くなりましたが、コマンドなど使ったことがない、Macにおけるターミナルの存在意義を見いだせない、という”コマンド蕁麻疹”の処方箋を3つ用意しました。次回予定しているMac OS X/Darwinのディレクトリ構成をお読みいただく前に、服用をお願いします。

・処方箋その1:ターミナルもファインダも目的は同じターミナルは、特別な処理を行うためのツールではありません。「シェル」という文字ベースのユーザインターフェイス(CUI)を通じ、システムに命令を伝えるにすぎません。GUIを使うかCUIを使うかは、言ってしまえば”ユーザの好みの問題”で、どちらか一方を選択するのではなく平行利用可能なところが、Mac OS Xの美点なのだと思います。
 ただし、CUIはユーザフレンドリーとは言い難いことも事実です。コマンドを利用した作業は、視覚的ではなく論理的、直感的というよりは観念的になりがちです。Mac OS XにはCUIを使わないという選択肢もあるので、必要なときだけ/必要な人だけ使う、というスタンスが正解でしょう。

・処方箋その2:コマンドを暗記する必要はない ターミナルを使う場合でも、コマンドの書式を暗記する必要はありません。「man」というオンラインマニュアルを表示するコマンドを利用すれば、かんたんに調べることができますから。コマンド名を忘れてしまった場合も、「apropos」コマンドに続けて適当なキーワードを指定すれば、関連するコマ
ンドを表示できます。
 コマンドを毎回入力しなければならない、という考えも誤りです。試しに、ターミナルで[control]-[p]を何度か押してみてください。以前実行したコマンドが自動的に入力されるはずです。

・処方箋その3:カレントディレクトリを理解しよう CUIの力を必要とするときがターミナルの出番ですが、知っておかねばならない約束事がいくつかあります。
 その1つが、現在どのフォルダ(ディレクトリ)で作業しているかを示す「カレントディレクトリ」という概念です。結果をターミナル画面に表示してお終い、というコマンドでもないかぎり、実行結果の保存先はカレントディレクトリとなることが基本です。Cocoa/Carbonアプリケーションのように、黙っていても「書類」や「デスクトップ」に保存されるということはありません。
 ターミナルを起動すると、現在ログインしているユーザのホームフォルダがカレントディレクトリに設定されます。言い換えれば、カレントディレクトリを変更するコマンドを実行しないかぎり、ファインダで”家”として表示されるフォルダが、コマンドの実行結果が保存される領域となります。

■プロフィール
海上 忍(うなかみ・しのぶ)
ITライター&コラムニスト。紙媒体ではMac Fanと日刊スポーツ、オンライン媒体ではマイコミジャーナルやITmediaなどで計6本の連載を持つほか、取材や製品レビューも手がける。これまでに上梓した単行本は約30冊、近著は「改訂版Mac OS X ターミナルコマンド ポケットリファレンス」(技術評論社刊)。

書籍紹介                    GDBデバッギング入門

 解説担当:高橋政明

GDBデバッギング入門
  Richard M.Stallman and Roland H. Pesch著
  コスモ・プラネット訳
  株式会社アスキー ISBN 4-7561-3016-X  本体1,900円+税

 1999年に初版発行の少し古い本です。GDBのバージョン4.17で書かれたドキュメントの翻訳ですが書籍版原著(Debugging with GDB)はバージョン5.1.1対応に更新されているようです。古い本は絶版となるのが常ですがありがたいことに本書は増刷され、私は2005年の第1版第5刷を入手しました。

 GDBはgccなどの開発ツールのひとつとしてMac OS Xに搭載されているオープンソースのソースレベルデバッガです。Xcodeのデバッガを使っているなら(間接的に)GDBを使っていることになります。
/Developer/ADC Reference Library/documentation/DeveloperTools/gdbに英文ドキュメントがありますが、今回ご紹介した書籍はバージョンは違いますがこれの日本語訳です。

Debugging with GDB  The GNU Source-Level Debugger
file:///Developer/ADC%20Reference%20Library/documentation/DeveloperTools/gdb/gdb/gdb_toc.html

 なおインターネットを検索すると日本語のドキュメントもみつかります。

 GDBはグラフィカルインターフェースを持ちませんがXcodeがUIを担当しコマンドライン操作せずにデバグできています。直接GDBのコマンドを使えるようになると効率よくバグ退治ができるようになる場面も少なくないハズです。コンソール出力はコピーしてバグの報告書を作るとき等にも役に立ちます。
 そんなこともありXcodeのドキュメント(Xcode 2.3ユーザーガイド)にも
『「Debugging with GDB」を参照してください。』と度々出てきます。

 さらにGDBの威力はXcodeによる開発中だけに留まりません。ターミナルでgdbコマンドを使いクラッシュの原因を突き止めることも可能です。GDBはいろいろなCPUで利用でき、CやC++、Objective-CやObjective-C++はもちろん様々な言語(Modula-2やAdaなんて項目があります!)にも対応しているそうです。ですのでGDBのスキルを身につけることは無駄にはなりません。
 マルチコアを生かすためのマルチスレッドプログラミングではデバグ作業も難しくなりますが、GDBのスレッドデバグ機能が役に立つでしょう。

 GDBには興味があるが英文ドキュメントは敷居が高い場合に本書が手頃な入門書となるはずです。

▼出版社のweb
http://www.ascii.co.jp/books/books/detail/4-7561-3016-X.shtml

◇MOSAからのお知らせと編集後記は割愛します◇

 

MOSA Developer News   略称[MOSADeN=モサ伝]
        配信停止 mailto:mosaden-ml@mosa.gr.jp
 記事内容に関するご意見 mailto:mosaden-toukou@mosa.gr.jp
      記事投稿受付 http://www.mosa.gr.jp/?page_id=850
Apple、Mac OSは米国アップル社の登録商標です。またそのほかの各製品名等はそれぞれ各社の商標ならびに登録商標です。このメールの再配信、および掲載された記事の無断転載を禁じます。
特定非営利活動法人MOSA  http://www.mosa.gr.jp/
Copyright (C)2007 MOSA. All rights reserved.