メニューボタン
サポートチーム便り2011.02.23

IFSパスを解決する

Question

IFS パスをどのように解決すればよいでしょうか。「blah」などのパスがある場合、OS では基本ディレクトリーは自分のカレント・ディレクトリーである /example と想定されるため、/example/blah という結果になります。あるいは、パスが「/usr/local/httpd/../otherfiles」の場合、「/usr/local/otherfiles」と解決されます。この解決パスを返す API はありませんか。

Answer

PASE 環境にはパス名を解決する realpath() というルーチンがあります。しかし、IBM i 環境ではこの API はありません。したがって、私の意見では、最も簡単な解決方法は、現在の作業ディレクトリー (CWD) を解決したいディレクトリーに変更することです。chdir() API を使用してこれを行うことができます。次に getcwd() API を呼び出して、新しい CWD を取得します。これが解決されたパス名になります。ILE RPG でその方法を示します。

わからないと困りますので説明しますが、この技法はすでに存在する IFS パスにのみ機能します。存在しないディレクトリー名で使用しても、「No such path or directory (パスまたはディレクトリーが見つかりません)」というエラーが表示されます。

以下のような擬似プログラムになります。

  1. 後で返却できるようにオリジナルの CWD を取得します。
  2. CWD を解決するパス名に変更します。IBM i により強制的にパス名が解決されます。
  3. 新しい CWD を取得します。パス名の解決先が示されます。
  4. ジョブが開始時の CWD に戻るよう、CWD の設定をオリジナルの設定に戻します。

以下の RPG サブプロシージャーは、その擬似プログラムを実装しています。

P IFS_ResolveDir        B                      export
D IFS_ResolveDir        PI        5000a        varying
D  dir                           5000a        varying const

D origDir               s         5000a        static
D newDir                s         5000a        static
 /free                           
                                              
         if getcwd(%addr(origDir): %size(origDir)) = *null;
           ReportError();
           return;
         endif;

         if chdir(%trimr(dir)) = -1;
           ReportError();
           return;
         endif;
 
         if getcwd(%addr(newDir): %size(newDir)) = *null;
            chdir(%addr(origDir));
            ReportError();
            return;
         endif;
 
         chdir(%addr(origDir));
 
         return %str(%addr(newDir));
 /end-free
P          E

以下の例は、このルーチンを RPG プログラムから呼び出しています。

mydir = '/usr/local/httpd/../otherfiles';
  realdir = IFS_resolveDir(mydir);

この結果、「realdir」が「/usr/local/otherfiles」に設定されます。

前記のコードはサンプルに過ぎません。作業用の完全な例をダウンロードできます

あわせて読みたい記事

PAGE TOP