6

どこでもチェックしたので、質問を繰り返さないことを願っています。

作成中の C コードに移植可能な更新機能を追加したいと考えています。プログラムは特定の場所にない可能性があり、単一のバイナリに保持することをお勧めします (動的ライブラリの読み込みなし)

それから更新が完了したら、プログラムを再起動できるようにしたい (ループではなく、実際には HDD からリロードする)

LinuxのCでこれを行う方法はありますか?

4

2 に答える 2

10

プログラムがディスクのどこに保存されているかがわかっている場合は、次exec()のプログラムを実行できます。

char args[] = { "/opt/somewhere/bin/program", 0 };

execv(args[0], args);
fprintf(stderr, "Failed to reexecute %s\n", args[0]);
exit(1);

プログラムがディスク上のどこにあるかわからない場合は、を使用execvp()して$ PATHでプログラムを検索するか、調べてください。Linuxでは、/procファイルシステムを使用します—/proc/self/exe特に; これは実行可能ファイルへのシンボリックリンクであるため、値を取得するにはを使用する必要がありreadlink()ます。注意:readlink()読み取った文字列をnullで終了しません。

必要に応じて、更新後に再起動されることを新しいプロセスに示す引数を渡すように調整できます。私が提供した最低限の引数リストは、必要に応じて複雑にすることができます(現在編集用に開いているファイルのリスト、またはその他の適切な情報とオプション)。

また、再実行する前にクリーンアップすることを忘れないでください。たとえば、開いているファイルをすべてクリーンに閉じます。開いているファイル記述子は実行されたプロセスに継承されますが(またはで閉じるようにマークをexec付けない限り)、新しいプロセスは(引数リストで)指定しない限り、それらが何のためにあるのかわからないため、それらを使用することができません。彼らは、少なくとも助けを借りずに、プロセスを混乱させるだけです。FD_CLOEXECO_CLOEXEC

于 2012-12-18T16:03:30.697 に答える
2

はい、適切なexec()関数を呼び出す必要があります。絶対パス名を見つけるのが面倒な場合があります。必要がある:

  • 現在のディレクトリを に格納しmain()ます。
  • からargcおよび (すべて)のargv[]値を保存しmain()ます。

呼び出しexec()は現在のプロセスを置き換えるため、自分自身を再起動するために必要なことはそれだけです。また、開いているファイルを閉じるように注意する必要がある場合もあります。そうしないと、ファイルが自分自身に「継承」される可能性がありますが、これはほとんど必要ありません。

于 2012-12-18T16:02:54.113 に答える