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」に設定されます。

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

ページトップ

ボタン