ファイルが存在しないと思うようにプロセスをだます方法は?

ファイルが存在しないと思うようにプロセスをだます方法は?

~/.config/myprogramバッチキューシステムで対話的に使用できる設定を保存するプログラムがあります。インタラクティブに実行すると、このプログラムは私の設定ファイルを使用したいと思います。ただし、バッチモードで実行している場合は、関連するすべての設定を上書きするコマンドラインオプションを指定するため、構成ファイルは必要ありません。また、ネットワーク経由で設定ファイルにアクセスすると、プログラムの起動時に数秒が追加されます。ファイルが存在しない場合、プログラムはより早く起動します(各ジョブは約1分かかり、これはバッチジョブのスループットに大きな影響を与えます)。 。しかし、プログラムを対話的に使用しているので、プロファイルを移動/削除したくありません。自分のバッチジョブがクラスターでスケジュールされている期間(他のユーザーの使用量に基づいて)に応じて、バッチジョブに参加しながらインタラクティブにプログラムを使用したい場合があります。

(余談:このように遅いネットワークファイルのパフォーマンスはバグかもしれませんが、私はクラスタユーザーだけなので、解決するだけで修正することはできません。)

バッチ使用のために構成ファイルを読み取らない(または構成ファイルを読み取らないコマンドラインオプションを持つ)プログラムバージョンをビルドできますが、プログラムのビルド環境が正しく設計されていないため、設定が困難です。戻る。私はシステムのパッケージマネージャを介してインストールされたバイナリを使用することを好みます。

プログラムを変更せずに自分のプロファイルが存在しないかのように、プログラムの特定のインスタンスをだますようにするにはどうすればよいですか?フォームの周りにラッパーをしたいのですが、 pretendfiledoesntexist ~/.config/myprogram -- myprogram --various-options...他のソリューションも開いています。

答え1

プログラムはからファイルへのパスを確認できます$HOME/.config/myprogram。したがって、ホームディレクトリが別の場所にあることがわかります。たとえば、次のようになります。

HOME=/nowhere your-program

これで、プログラムにホームディレクトリに追加のリソースが必要になる可能性があります。それが何であるかを知っている場合は、プログラムに必要なリソースへのリンクを含むプログラム用の偽のホームページを準備できます。

mkdir -p ~/myprogram-home/.config
ln -s ~/.Xauthority ~/myprogram-home/
...
HOME=~/myprogram-home myprogram

答え2

LD_PRELOAD他のすべての方法が失敗した場合は呼び出しを傍受しますopen("/home/you/my-program/config.interactive")が、他の呼び出しは通過するように挿入するラッパーライブラリを作成してください。これはシステムコールをフィルタリングするので、あらゆる種類のプログラムでもシェルスクリプトでも機能します。

extern int errno;

int open(const char *pathname, int flags)
{
  char *config_path = get_config_file_path();
  if (!strstr(pathname, config_path))
  {
    return get_real_open(pathname, flags);
  }
  else
  {
    errno = ENOENT;
    return -1;
  }
}

注:このコードをテストしていないため、errnoこの部分が機能しているかどうか100%確信できません。

どのように進行しているかを確認してくださいfakerootgetuid(2)などの呼び出しに対してこれを行いますstat(2)

デフォルトでは、リンカはアプリケーションをライブラリにリンクし、openシンボルを上書きします。独自のライブラリでは、名前付きの2つの異なる関数を使用できないため、openそれを2番目の部分(たとえば)に分割する必要があります。get_real_openこれは元のopen呼び出しに戻ります。

オリジナル:./Application

Application -----> libc.so
            open()

ブロック:LD_PRELOAD=yourlib_wrap.so ./Application

Application -----> yourlib_wrap.so --------------> yourlib_impl.so -----> libc.so
            open()                 get_real_open()                 open()

編集する:確かに二重接続に依存せずにラッパーを作成できるldフラグ()を有効にできます。--wrap <symbol>

/* yourlib.c */
#include <stdio.h>

int __real_open(const char *pathname, int flags)

int __wrap_open(const char *pathname, int flags)
{
  char *config_path = get_config_file_path();
  if (!strstr(pathname, config_path))
  {
    /* the undefined reference here will resolve to "open" at linking time */
    return __real_open(pathname, flags);
  }
  else
  {
    errno = ENOENT;
    return -1; 
  }
}

答え3

構成ファイルを別の場所に移動し、ファイルを通常のターゲットにコピーし、プログラムを実行し、終了時に削除する対話型ユースケース用のシェルスクリプトラッパーを作成します。

答え4

たとえば、設定ファイルの名前を次のようにconfig.interactive変更しますconfig.script

configこれで、必要な実際の構成へのソフトリンク(またはアプリケーションが構成ファイルとして期待する名前)を作成し、アプリケーションを実行します。

ln -s config.interactive config

後でリンクを整理することを忘れないでください。

関連情報