【问题标题】:How do I use ioctl in a daemon?如何在守护进程中使用 ioctl?
【发布时间】:2021-06-06 01:09:15
【问题描述】:

我按照link 在 Linux 中创建了一个守护进程。在我开始调用 ioctl 之前它运行良好。似乎对 ioctl 的任何调用都被完全忽略了。我正在使用 ioctl 设置终端和键盘模式。示例代码如下。该代码无需将其作为守护程序运行即可工作。我必须做其他事情才能让 ioctl 工作吗?

int main(int argc, char **argv)
{
    skeleton_daemon(); // Function is the exact same as in the link
    int term = open("/dev/tty1", O_RDWR);

    syslog(LOG_NOTICE, "First daemon started.");
    sleep(5);
    

    // Should freeze the terminal and keyboard input but doesn't when running as daemon
    ioctl(term, KDSETMODE, KD_GRAPHICS);
    ioctl(term, KDSKBMODE, K_OFF);
    ioctl(term, 0x4B51, 1);

    sleep(5);

    ioctl(term, KDSETMODE, KD_TEXT);
    ioctl(term, KDSKBMODE, previousMode);
    ioctl(term, 0x4B51, 0);

    syslog(LOG_NOTICE, "First daemon terminated.");
    closelog();
    return EXIT_SUCCESS;
}

【问题讨论】:

  • 正如@Glärbo 的回答中所解释的,守护进程没有控制 tty。它与它分离。您引用的链接将其分离。即使它有一个,这个控制终端也会是“/dev/tty”,它是进程控制终端的同义词(不是硬编码值/dev/tty1)。

标签: c linux daemon ioctl


【解决方案1】:

守护进程没有控制终端(或根本没有 a 终端),并且它们的标准输入通常从/dev/null 重定向。他们的标准输出和标准错误要么被重定向到/dev/null,要么被重定向到一个日志文件。

即使守护程序有终端,这些 ioctl 也只会影响该终端,而不影响其他用户。

【讨论】:

  • 但这就是我重新打开终端的原因。如果我重新打开它,它应该不会影响它吗?假设我使用带有 fd 术语的 write 系统调用,它将作为守护进程写入终端,那么为什么八进制不起作用?
  • @person:“影响”?这完全取决于您打算做什么。控制台 ioctl 仅在该控制台是当前虚拟控制台时才会影响事物。如果您查看 X.org 或 Wayland,他们使用 openvt 获取第一个未使用的虚拟终端(使用 -s 开关)或使用 chvt 切换到专用虚拟终端(通常是 /dev/tty7)。跨度>
  • 哦,我明白了。 ioctl 仅适用于进程控制的终端。可以省略setsid函数来保留终端吗?因为当我这样做时,它会完全按照我的意愿工作。
  • @person:不,这是一个单独的问题。如果您希望终端成为您的控制终端,请使用 TIOCSCTTY ioctl(请参阅man 4 tty_ioctl)。您需要做一个(fork 和子进程)setsid() 以确保当前进程是没有控制终端的新会话的进程组负责人,然后打开 tty,并在该 tty 上使用 TIOCSCTTY ioctl使其成为控制终端。对于许多控制台 ioctl,这还不够,因为该特定虚拟控制台也必须是 ioctl 工作的当前控制台。正如我所写,这完全取决于您要做什么。
  • 啊,这正是我所需要的!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-14
  • 1970-01-01
相关资源
最近更新 更多