1
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <assert.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <string.h>

char *getdir()  /*find working directory*/
{
  char *buffer;/*buffer is going to be used in getcwd function to get the current directory*/
  char *path_buffer;//path_buffer is going to contain the directory//
  long maxsize = pathconf(".", _PC_PATH_MAX);/* we set maxsize as the maximum pathname length*/
  if((buffer=(char*) malloc((size_t)maxsize))!=NULL)
    {
      path_buffer=getcwd(buffer,maxsize); /*get the current directory*/
      printf("\nMy working directory = %s",path_buffer);
      return path_buffer;
    }
  else{
    exit(-1);
  }
}

char * getcmline() /*get command from stdin by the user*/
{
  int bytes_read;
  int nchars=200;/*max possible number for the input of the user*/
  int nbytes=(sizeof(char))*nchars; /*size of chars in bytes*/
  char *line=(char*) malloc(nbytes+1);
  bytes_read=getline(line,&nbytes,stdin);/*read line from stdin*/
  if(bytes_read == -1){
    printf("Read line error");
    exit(-1);
  } /*error handling for bytes_read*/
  else{
    if(line[strlen(line)-1]=='\n')
      {
        line[strlen(line)-1]='\0'; /*change new line character in the end of the line of stdin*/
      }
  }
  return line;
}

int main(void)
{
  pid_t pid,child_pid;
  int rv=0;
  char* exit_string="exit";
  char *path_buffer=NULL;
  int nchars=200;
  int nbytes=(sizeof(char))*nchars;
  char *line=malloc(nbytes+1);
  char *commands[2];
  while(1){
    switch(pid = fork())
      {
      case -1:
        perror("fork"); /* something went wrong */
        exit(1);
      case 0:
        printf(" CHILD: This is the child process!\n");
        child_pid=getpid();
        printf(" CHILD: My PID is %d\n", child_pid);
        path_buffer=getdir();/*get the directory path*/
        line=getcmline();/*get a command by the user*/
        if(strcmp(line,exit_string)==0)
          {
            rv=3;
            exit(rv);
          }
        commands[0]=line;
        commands[1]=NULL;
        execvp(commands[0],commands);
        perror("Execution error");
        exit(-1);



      default:
        waitpid(-1, &rv, 0);
        if(WIFEXITED(rv)){
          printf("Child exited normally and child's exit status is: %d\n", WEXITSTATUS(rv));
          if((WEXITSTATUS(rv))==3){
            exit(1);
          }
        }
      }
  }
  return 0;
}

我在 中进行了更改getlinerv并为execvp. 但是现在发生的错误是在我输入例如“ls”之后。它说:

执行错误:没有这样的文件或目录。

再次感谢您的帮助和我缺乏知识。

错误似乎在行变量中,但我无法理解问题所在!

C中的字符数组和getline

这里给出了解决方案。它应该是 line[(strlen)-1] 而不是 line[(strlen-1)]

4

3 回答 3

4

父母永远不会得到孩子的 pid,因此 waitpid 不会等待它。waitpid(-1,...) 将等待任何子进程完成后再继续。

我还建议缩进 case 并以 break 结束每个 case 语句;

于 2012-09-17T19:39:58.523 回答
1

所以,对于警告:你知道这些数字指的是什么行,我不得不猜测:你可以让这更容易!

int rv=NULL;

初始化从没有强制转换的指针生成整数 [默认启用] 第 42 行

NULL 是一个指针值,rv 是一个整数。0如果这就是您的意思,请将其设置为。

execvp(line[0],line);

传递 'execv' 的参数 1 使指针从没有强制转换的整数 [默认启用] 第 64 行从不兼容的指针类型 [默认启用] 第 64 行传递'execv' 的参数 2

如果您正在调用execv,则您正在编译的代码不是您发布的代码。然而 ...line是 a char *line[0]a 也是charexecvor的第一个参数execvpconst char *

execv 试图完成什么?它需要一个程序名称来运行(第一个参数,const char *)和一个参数数组(这些将形成argv[]传递给新程序main函数的数组,并且数组中的最后一项必须为 NULL)。

char *line=(char*) malloc(nbytes+1);
bytes_read=getline(&line,&nbytes,stdin);/*read line from stdin*/

从不兼容的指针类型[默认启用]第 29 行传递“getline”的参数 2

getline需要缓冲区的地址才能将字符放入......line 就是这样一个地址。&line但是,是指针的地址。只需取出&.


您的代码中存在更多问题,但这些警告都有一些共同点:

  • 你似乎不明白函数需要什么类型,
  • 你的变量是什么类型,
  • 你实际传递的是什么类型,
  • 或者编译器抱怨您的类型不匹配时的含义

在开始尝试编写多进程程序之前,您需要了解这一点。用一些简单的东西来学习它,学习阅读文档,并理解编译器警告。

于 2012-09-17T21:06:13.200 回答
0
default:
waitpid(child_pid, &status, 0);
//wait(&rv);
printf("PARENT:My child's exit status is: %d\n", WEXITSTATUS(rv));
if((WEXITSTATUS(rv))==3){exit(1);}

您将未初始化的变量传递child_pidwaitpid,该变量仅在子进程中设置。你应该通过pid。使用未初始化的变量会导致未定义的行为,因此无法预测会发生什么。WEXITSTATUS你也用另一个未初始化的变量调用rv,你应该通过status那里。

孩子在这里什么都不做,因为

path_buffer=getcwd(buffer,sizeof(buffer));

传递给的 size 参数getcwd是 a 的大小char*,通常是 4 或 8 个字节,这对于大多数目录的绝对路径来说太短了,path_buffer is set toNULL and the child immediately exits. You should pass the size of the buffer,maxsize` 在那里。

于 2012-09-17T19:41:56.847 回答