【问题标题】:Fork-server and grandchildren for exec用于 exec 的分叉服务器和孙子
【发布时间】:2013-03-01 23:29:23
【问题描述】:

我需要关于 fork-server 的帮助。我想要做的是接受一个客户端然后分叉让其他客户端连接,同时将标准输出和错误重定向到客户端。然后客户端应该能够发送应该由位于孙子中的 execlp() 执行的字符串。

我无法找到我的逻辑错误..

在 main() 中:

    while (1) {

        t = sizeof(remote);

        printf("Waiting for connection.\n");

        s2 = accept(s, (struct sockaddr*)&remote, &t);

        if (s2 == -1) {
            perror("accept");
            exit(1);
        } else {

            printf("Client connected.\n");

            if(!fork()) {

                close(1);
                dup(s2);
                handle(s2);
                exit(0);               
            }
            close(s2);
        }
    }

在句柄()中:

    char str[100];
    int n;

    while(1) {

        n = recv(client_socket, str, 100, 0);

        if(n <= 0) {

            perror("recv");
            exit(1);
        } else {

            if(!fork()) {

                execlp("/bin/sh", "sh","­-c", str, NULL);
                exit(1);
            } 
            wait(0);
        } 
    } 

execlp的结果没有重定向到客户端,报错“sh: Can't open c”。

【问题讨论】:

  • 在控制台“/bin/sh sh c”上执行此操作会得到什么
  • 我猜是因为我在 fork 外部测试了 execlp 并且它可以工作。
  • 当我在控制台中输入“/bin/sh sh c”时,我得到了同样的错误
  • str 的值是多少?是否正确终止?

标签: c exec fork


【解决方案1】:

您应该写:execlp("/bin/sh", "sh","-c", str, NULL); 将选项“-c”传递给 shell。您正在传递选项 "c",它被解释为:运行名为 c 的脚本,它不存在。

见:http://unixhelp.ed.ac.uk/CGI/man-cgi?sh

另一件事:你应该在读取字符串后 NUL 终止它:

if(n > 0)
    str[n] = '\0';

您还应该只读取 99 个字符,因为您将在字符串末尾写入 '\0' 字符。

【讨论】:

  • 很抱歉,问题中打错字了,“-c”,
【解决方案2】:

一个可能的原因是您尝试运行的命令不在命令搜索路径中。

另一个原因可能是您获取的字符串包含命令 它的参数,并将其作为单个参数传递给 execlp 会将其作为单个参数传递给 shell,因此它认为整个字符串就是命令。

如果是最后一个,那么您需要将命令及其参数拆分为类似 argv 的数组,并改用 execvp

正确终止字符串也很重要。连接客户端是否使用终止 '\0' 字符发送?如果没有,那么您需要自己添加(在这种情况下,您只能接收 99 个字符)。

【讨论】:

  • 客户端没有问题,当我将 Var str 更改为“ls”或任何命令时它仍然给出错误。
猜你喜欢
  • 2023-04-04
  • 1970-01-01
  • 2017-06-02
  • 1970-01-01
  • 2011-06-07
  • 1970-01-01
  • 2014-10-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多