通过C中的argv使用管道发送和接收字符数组

时间:2016-09-27 01:16:00

标签: c pipe exec argv execl

所以,我正在尝试创建一个管道,通过argv []连接的管道来回发送char数组。现在,我停留在接口中接收数组(从父节点发送到子节点的c_param的param)。接收db.c中的字符3和5。我知道3和5是我的管道所在的argv []的索引,但是我不知道如何接受它并在db.c中打印出我的消息。

interface.c创建管道,分叉到父进程和子进程。 char数组参数转移到子进程到char数组c_param。使用snprintf,我将我的管道变成了一个char,使用execl和我的char数组c_param发送。

interface.c:

int main (int argc, char *argv[])
{
  int to_Child[2];
  int to_Parent[2];
  int id, toChildPipe, toParentPipe, err;
  char param[100] = "This is the parameter!";
  char sendPipe[100];
  char recPipe[100];

  /*CREATING PIPE*/
  toChildPipe = pipe(to_Child);
  toParentPipe = pipe(to_Parent);


  if(toChildPipe == -1 || toParentPipe == -1)
  {
    printf ("Error on pipe creation: %d", errno);
    exit (1);
  }

  /*Creating Child Process*/
  id = fork();
  if(id == 0)
  {
    /**
     *
     * IN THE CHILD Process
     *
     */
    close(to_Child[1]); //reading
    close(to_Parent[0]); //writing
    char c_param[100];


    toChildPipe = read(to_Child[0], c_param, 100);
    if (toChildPipe == -1)
    {
      //If failed
      printf("Error on read from pipe from parent: %d\n",errno);
      //exit with error
      exit(2);
    }//Error pipe from parent


    snprintf(sendPipe,sizeof(sendPipe), "%d",to_Parent[0]);
    snprintf(recPipe,sizeof(recPipe), "%d",to_Child[0]);

    err = execl("./db","db",sendPipe,recPipe,(char *)0);
      if(err == -1)
      {
        printf("Error on execl: %d\n", errno);
      }//Error execl

      toChildPipe = read(to_Child[0], c_param, 100);
      if (toChildPipe == -1)
      {
        //If failed
        printf("Error on read from pipe from parent: %d\n",errno);
        //exit with error
        exit(2);
      }//Error pipe from parent

    }//CHILD PROCESS

  else if (id > 0)
  {
    /**
     *
     *IN THE PARENT PROCESS
     *
     */
    close(to_Child[0]); //writing
    close(to_Parent[1]); //reading


    toChildPipe = write(to_Child[1],param,100);
    if(toChildPipe == -1)
    {
      printf("Error on write to pipe: %d", errno);
      exit(3);
    }
    /*Piping was successful!*/
    exit(0);
  }//PARENT PROCESS
  else
  {
    exit(4);
  }
}

db.c从interface.c execl启动,应该通过argv []接收参数,然后将其打印出来。 db.c

#include        <errno.h>
#include        <stdio.h>
#include        <stdlib.h>
#include        <string.h>
#include        <sys/types.h>
#include        <unistd.h>


int main(int argc, char *argv[])
{
  FILE *finput;
  int j = 0;
  int fd;
  int toChildPipe;
  char c_param[100];

  if(argc > 1)
  {
    for(j ; j < argc ; j++)
    printf("argv = %s\n", argv[j]);
    printf("argc = %d\n",argc);
  }
  fd = atoi(argv[1]);
  printf("Statement: %s\n", argv[fd]);

  strcpy(c_param, argv[3]);
  printf("filename: %s\n", c_param);

}

这是我得到的当前输出,我知道5和3是我需要发送消息并接收我正在尝试在db.c中打印的消息的索引

输出(db.c):

argv = db
argv = 5
argv = 3
argc = 3
Statement: TERM=xterm

我希望我能给你足够的信息,我感谢你愿意给我的任何帮助。提前谢谢!

1 个答案:

答案 0 :(得分:0)

有很多小事错了。你最大的问题是[ODBC Data Sources] [odbcname] [Default] 中关于db.c传递给它的参数的假设/断言 - 传递的内容和预期的内容完全不匹配。 interface.c中还有大量无关的代码。特别是,子项在执行interface.c之前从管道中读取,因此管道上没有任何内容可供db读取。

这里是“固定的”&#39;代码,一些调试代码仍然存在。

db

interface.c

### #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> int main(void) { int to_Child[2]; int to_Parent[2]; int id; char param[100] = "This is the parameter!"; char sendPipe[100]; char recPipe[100]; if (pipe(to_Child) == -1 || pipe(to_Parent) == -1) { printf("Error on pipe creation: %d", errno); exit(1); } printf("Pipes: C(%d,%d), P(%d,%d)\n", to_Child[0], to_Child[1], to_Parent[0], to_Parent[1]); id = fork(); if (id == 0) { close(to_Child[1]); // Child does not write to itself close(to_Parent[0]); // Child does not read what it writes snprintf(sendPipe, sizeof(sendPipe), "%d", to_Parent[1]); snprintf(recPipe, sizeof(recPipe), "%d", to_Child[0]); execl("./db", "db", sendPipe, recPipe, (char *)0); fprintf(stderr, "Error on execl: %d\n", errno); exit(2); } else if (id > 0) { close(to_Child[0]); // Parent does not read childs input close(to_Parent[1]); // Parent does not int nbytes = write(to_Child[1], param, 100); if (nbytes == -1) { fprintf(stderr, "Error on write to pipe: %d\n", errno); exit(3); } close(to_Child[1]); if ((nbytes = read(to_Parent[0], param, 100)) <= 0) { fprintf(stderr, "Error on read from pipe: %d\n", errno); exit(5); } printf("Data from pipe: [%.*s]\n", nbytes, param); exit(0); } else { perror("fork failed"); exit(4); } }

db.c

样品运行

#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char *argv[])
{

    printf("argc = %d\n", argc);
    for (int j = 0; j < argc; j++)
        printf("argv[%d] = %s\n", j, argv[j]);

    if (argc != 3)
    {
        fprintf(stderr, "Usage: %s write-fd read-fd\n", argv[0]);
        return 1;
    }
    int ofd = atoi(argv[1]);
    int ifd = atoi(argv[2]);
    printf("ifd = %d; ofd = %d\n", ifd, ofd);

    char c_param[100];
    int nbytes = read(ifd, c_param, sizeof(c_param));
    if (nbytes <= 0)
    {
        fprintf(stderr, "Error: failed to read any data (%d)\n", errno);
        return 1;
    }
    printf("Child: [%.*s]\n", nbytes, c_param);

    assert(strlen(c_param) + sizeof(" - sent back to parent") <= sizeof(c_param));
    strcat(c_param, " - sent back to parent");

    if (write(ofd, c_param, nbytes) != nbytes)
    {
        fprintf(stderr, "Error: failed to write all the data (%d)\n", errno);
        return 1;
    }

    return 0;
}

请注意,代码会将错误报告给标准错误(这就是它的用途)。它还可以划分打印数据,使其更容易被发现 意外的问题。它并不假设数据是空填充的;它将打印的长度限制为读取的长度,但事实上数据最后有很多空值。