启用 linux 服务以显示弹出窗口 window

Enable a linux service to show popup window

我使用 C 语言开发了一个 IP 信使,我想分享它的一些实现细节,以便完全理解我的问题。

  1. 使用 GTK+-2.0 库显示 GUI windows。
  2. 它有一个侦听套接字,每当有新连接到达时,它就会创建一个新进程来为该连接提供服务。
  3. 每当有新消息到达时,它都会显示一个 GUI window 来显示收到的消息(如弹出窗口 window)。
  4. 它需要 运行 的 root 权限,因为它使用原始套接字发送 ICMP 回显数据包来识别本地网络中的可用主机。 (RAW套接字需要超级权限)
  5. 该进程被妖魔化了,因此它将 运行 在后台并仅在收到消息时显示弹出窗口。
  6. 我的机器是CentOS 6.9

当我从终端启动这个过程时,一切都很完美。但是后来我通过在 /etc/init.d/ 目录中添加启动脚本,为这个程序创建了一个启动条目 运行 它作为一项服务。 然后我使用服务命令启动了我的服务,

 # service ipmsnger start

现在我可以使用 ps 命令看到进程 运行ning。但如果消息到达,它不会显示弹出窗口 window。消息发件人从信使那里获得成功发送报告。会是什么原因?用户从终端启动恶魔进程与系统将其作为启动服务启动有什么区别?

我不是很熟悉 init.d,因为现在 systemd 更常见。 我假设您是 运行ning X11 而不是 Wayland。

要么使用 CAP_NET_RAW 运行 你的程序作为用户应该显示对话框。

或者运行程序为root,显示的时候换成用户的UID显示。 您还必须将 DISPLAY 主要是 :0DBUS_SESSION_BUS_ADDRESS 设置为 unix:path=/run/user/<UID of user to display to>/bus


libnotify 示例。

#include <libnotify/notify.h>
#include <unistd.h>
#include <errno.h>

int main(void) {
    if (getuid() != (uid_t)1000 && setuid(1000) == -1) {
        perror("setuid");
        return -1;
    }
    if (setenv("DISPLAY", ":0", 0) == -1) {
          perror("setenv DISPLAY");
          return-1;
    } // guessing 1000 as UID
    if (setenv("DBUS_SESSION_BUS_ADDRESS", "unix:path=/run/user/1000/bus", 1) == -1) {
        perror("setenv DBUS");
        return-1;
    }

    notify_init ("Hello world!");
    NotifyNotification * Hello = notify_notification_new("Hello world",
            "This is an example notification.", "dialog-information");
    notify_notification_show(Hello, NULL);

    g_object_unref(G_OBJECT(Hello));
    notify_uninit();

    return 0;
}

当您从终端 window 启动程序时,它与您当前的登录会话相关联。这为它提供了在您的 GUI 中显示弹出窗口所需的上下文。

但请记住 Linux 是一个多用户系统,甚至支持多个并发 GUI 会话。每个 GUI 属于一个会话;机器没有任何真正的 GUI。如果您将程序作为系统服务启动,那么它不会与任何特定的登录会话连接,因此它不知道您的 GUI 在那里显示任何内容。

鉴于服务 运行 具有 root 权限,它可能会发现登录会话并在其中弹出消息,但您不是免费获得的。

我推断 运行将您的程序作为服务的目的是让无法断言 root 特权的人可以使用它。在这种情况下,我建议重构为两个程序:一个 运行 作为 root 的服务,以及一个 运行 没有特权的客户端。用户应该 运行 客户端,就像他们自己一样,在他们想要接收弹出窗口的会话中。客户端向服务器注册自己。服务器接收来自网络的消息并将它们分发给已注册的客户端以供它们显示。