与可可的守护进程

时间:2011-11-27 14:56:10

标签: macos cocoa daemon launchd

我写了一个FTP服务器,通过ftpd.command从命令行启动。 现在我想从Cocoa应用程序运行该命令。

我想退出应用程序,命令应该继续运行。 当我返回Cocoa应用程序时,它应该知道,如果FTP服务器仍在运行。

有人可以帮助我吗? 非常感谢! 儒略

3 个答案:

答案 0 :(得分:2)

您应该使用launchd来处理FTP服务器。它专门针对您描述的情况而设计,即启动和管理后台服务。

您需要创建一个launchd配置文件,该文件可以放在以下位置之一:

  • ~/Library/LaunchAgents:用户提供的每用户代理。
  • /Library/LaunchAgents:管理员提供的每用户代理。
  • /Library/LaunchDaemons:由系统提供的系统守护进程 管理员。

守护程序 是一种系统范围的服务,其中所有客户端都有一个实例。 代理 是一种基于每个用户运行的服务。

launchd Configuration files采用property list.

的形式

您需要创建一个launchd配置plist并将其放在上述位置之一。您可以配置plist,以便launchd在启动时或定期运行您的服务,或者响应各种操作(例如更改文件夹的内容)。

要检查您的作业是否正在运行,您需要使用Service Management framework。您可以像launchd那样询问CFDictionaryRef jobDict = SMJobCopyDictionary(kSMDomainUserLaunchd, CFSTR("com.your.apps.bundle.id")); 的工作状态:

jobDict

如果找不到作业,则NULL将为kSMDomainUserLaunchd

(如果您使用的是系统级守护程序,那么您将kSMDomainSystemLaunchd替换为{{1}}。

答案 1 :(得分:0)

我认为你必须调整你的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;
}

答案 2 :(得分:0)

在GitHub上查看我的项目TabletMagic的源代码。它有一个Cocoa偏好窗格,用于启动用户空间守护程序,还可以管理启动项。 Cocoa部分使用外部帮助程序来执行所有特权任务,这是在第一次启动时自行设置的 - 在Cocoa应用程序的特权上下文中要求管理员授权。这是所有标准程序,尽管不是纯粹的可可。