私はFTPサーバーを作成しましたが、witchはftpd.commandを介してコマンドラインから起動されます。ここで、Cocoaアプリからそのコマンドを実行したいと思います。
アプリを終了したいのですが、コマンドは実行されたままになります。そして、Cocoaアプリに戻ると、FTPサーバーがまだ実行されているかどうかがわかります。
私を助けてくれる人はいますか?どうもありがとう!ジュリアン
launchd
FTP サーバーを処理するために使用する必要があります。これは、あなたが説明した状況、つまりバックグラウンド サービスの起動と管理のために特別に設計されています。
launchd
次のいずれかの場所に配置できる構成ファイルを作成する必要があります。
~/Library/LaunchAgents
: ユーザーが提供するユーザーごとのエージェント。/Library/LaunchAgents
: 管理者によって提供されるユーザーごとのエージェント。/Library/LaunchDaemons
: 管理者によって提供されるシステム全体のデーモン。デーモンは、すべてのクライアントに対して 1 つのインスタンスがあるシステム全体のサービスです。エージェントは、ユーザーごとに実行されるサービスです。
launchd
構成ファイルは、プロパティ リストの形式になっています。
launchd
構成 plist を作成し、上記の場所のいずれかに配置する必要があります。launchd
起動時または定期的に、またはさまざまなアクション (フォルダーのコンテンツの変更など) に応答して、サービスを実行するように plist を構成できます。
ジョブが実行されているかどうかを確認するには、サービス管理フレームワークを使用する必要があります。launchd
次のようにジョブのステータスを尋ねることができます。
CFDictionaryRef jobDict = SMJobCopyDictionary(kSMDomainUserLaunchd, CFSTR("com.your.apps.bundle.id"));
ジョブが見つからなかった場合は にjobDict
なりますNULL
。
(システムレベルのデーモンを使用している場合は、に置き換えますkSMDomainUserLaunchd
) kSMDomainSystemLaunchd
。
完了するまでコマンドラインを「ブロック」しないように、FTPサーバーを調整する必要があると思います。私はここでいくつかのサンプルコードを見つけました:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/fcntl.h>
#include <unistd.h>
void start_daemon(void)
{
chdir("/");
setsid();
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
open("/dev/null", O_RDWR);
dup(STDIN_FILENO);
dup(STDIN_FILENO);
for(;;)
sleep(100);
}
int main(int argc, char *argv[])
{
pid_t pid;
if ((pid = fork()) < 0)
{
perror("fork() failed");
return 1;
}
if (pid == 0)
start_daemon();
printf("Child has PID %i.\n", pid);
return 0;
}
GitHub にある私のプロジェクト TabletMagic のソース コードを見てください。ユーザー空間デーモンを起動する Cocoa 設定ペインに加えて、launchd 項目を管理します。Cocoa 部分は、外部ヘルパーを使用してすべての特権タスクを実行します。これは、最初に起動したときに自己設定されます (管理者の承認を求める Cocoa アプリによる特権コンテキストで)。純粋なココアではないにもかかわらず、これはすべて標準的な手順です.