Пишу свою собственную оболочку, необъявленный идентификатор «output» - PullRequest
0 голосов
/ 03 июня 2018

Вот мой код для моей собственной оболочки на C. При компиляции я получаю сообщение об ошибке: использование необъявленного идентификатора 'output'.Вот примеры некоторых ошибок при компиляции:

ошибка: использование необъявленного идентификатора 'output' char input [100]; output [100];

test3.c:53:15: ошибка: использование необъявленного идентификатора 'output' strcpy (output, args [i + 1]);^

test3.c: 53: 15: ошибка: использование необъявленного идентификатора 'output'

test3.c: 60: 8: предупреждение: неявное объявление функции 'open' недопустимо вC99 [-Wimplicit-function-объявление] j = open (input, O_RDONLY, 0);^

test3.c: 60: 20: ошибка: использование необъявленного идентификатора 'O_RDONLY' j = open (input, O_RDONLY, 0);^

test3.c: 61: 29: ошибка: использование необъявленного идентификатора 'O_RDONLY' if ((j = open (input, O_RDONLY, 0)) <0) {</p>

test3.c: 70: 12: предупреждение: неявное объявление функции 'creat' недопустимо в C99 [-Wimplicit-function-объявление] if ((i = creat (output, 0644)) <0) {</p>

test3.c: 70: 18: ошибка: использование необъявленного идентификатора 'output' if ((i = creat (output, 0644)) <0) {</p>

Вот мой код:

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "signal.h"
#include "unistd.h"

void prompt(char*);
void execute( char* );
char** parse( char* );

int main( int ac, char* av[] )
{
  char input[255]; // buffer for supporting command

  signal( SIGINT, SIG_IGN ); // ignore ctrl-c

  while(1)
  {
    prompt(input);
    execute( input );
  }
};

void execute( char* str)
{
  int fork_result, status, i = 0,j=0,in=0,out=0;
  char input[100];output[100];
  char** args = parse( str ); // splits the user command into arguments

  fork_result = fork(); // attempt to fork
  if ( fork_result == -1 ) // failure
  {
    perror("Failed to fork\n");
    exit(1);
  }
  else if ( fork_result == 0 ) // I'm the child
  {
    for(i=0;args[i]!='\0';i++)
    {
      if(strcmp(args[i],"<")==0)
      {   
        args[i]=NULL;
        strcpy(input,args[i+1]);
        in=2;   
      }   
      if(strcmp(args[i],">")==0)
      {
        args[i]=NULL;
        strcpy(output,args[i+1]);
        out=2;
      }   
    }

    if (in) 
    {
      j = open(input, O_RDONLY, 0);
      if ((j = open(input, O_RDONLY, 0)) < 0) 
      {
        perror("Couldn't open input file");
        exit(0);
      }
      dup2(j, 0);
      close(j);
    }

    if (out) 
    {
      if ((i= creat(output , 0644)) < 0) 
      {
        perror("Couldn't open the output file");
        exit(0);
      }
      dup2(i, STDOUT_FILENO);
      close(i);
    }

    execvp( args[0], args );
    perror("failed to exec\n");
    exit(2);
  }
  else // I'm the parent
  {
    // wait here
    wait(&status); // wait for child to finish
    free( args ); // free dynamic memory
  }
}

char** parse( char* str )
{
  char** args = malloc( 256 );
  int i = 0;

  args[i] = strtok( str, " " );

  while( args[i] )
  {
    i++;
    args[i] = strtok( NULL, " " );
  }

  return args;
}

void prompt(char* input)
{
  printf("$ "); // print prompt
  fgets( input, 255, stdin );

  input[strlen(input)-1] = '\0'; // overwrite \n with \0

  if ( strcmp( input, "exit" ) == 0 ) // shell command
    exit(0);
}

Ответы [ 2 ]

0 голосов
/ 03 июня 2018

В вашем коде несколько ошибок.

1. В строке 27 вам нужно разделить два определения переменных ввода и вывода запятой вместо точки с запятой char input[100], output[100];или укажите тип вывода, например char input[100]; char output[100]; Вы уже сделали это в строке выше.

2. Компилятор жалуется на отсутствие определений функции open и идентификатора O_RDONLY.Это можно исправить, добавив #include "fcntl.h" к вашим включениям в верхней части файла.

После этих изменений код прекрасно скомпилируется для меня (с gcc 5.4.0):

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "signal.h"
#include "unistd.h"
#include "fcntl.h"

void prompt(char*);
void execute( char* );
char** parse( char* );

int main( int ac, char* av[] )
{
  char input[255]; // buffer for supporting command

  signal( SIGINT, SIG_IGN ); // ignore ctrl-c

  while(1)
  {
    prompt(input);
    execute( input );
  }
};

void execute( char* str)
{
  int fork_result, status, i = 0,j=0,in=0,out=0;
  char input[100], output[100];
  char** args = parse( str ); // splits the user command into arguments

  fork_result = fork(); // attempt to fork
  if ( fork_result == -1 ) // failure
  {
    perror("Failed to fork\n");
    exit(1);
  }
  else if ( fork_result == 0 ) // I'm the child
  {
    for(i=0;args[i]!='\0';i++)
    {
      if(strcmp(args[i],"<")==0)
      {   
        args[i]=NULL;
        strcpy(input,args[i+1]);
        in=2;   
      }   
      if(strcmp(args[i],">")==0)
      {
        args[i]=NULL;
        strcpy(output,args[i+1]);
        out=2;
      }   
    }

    if (in) 
    {
      j = open(input, O_RDONLY, 0);
      if ((j = open(input, O_RDONLY, 0)) < 0) 
      {
        perror("Couldn't open input file");
        exit(0);
      }
      dup2(j, 0);
      close(j);
    }

    if (out) 
    {
      if ((i= creat(output , 0644)) < 0) 
      {
        perror("Couldn't open the output file");
        exit(0);
      }
      dup2(i, STDOUT_FILENO);
      close(i);
    }

    execvp( args[0], args );
    perror("failed to exec\n");
    exit(2);
  }
  else // I'm the parent
  {
    // wait here
    wait(&status); // wait for child to finish
    free( args ); // free dynamic memory
  }
}

char** parse( char* str )
{
  char** args = malloc( 256 );
  int i = 0;

  args[i] = strtok( str, " " );

  while( args[i] )
  {
    i++;
    args[i] = strtok( NULL, " " );
  }

  return args;
}

void prompt(char* input)
{
  printf("$ "); // print prompt
  fgets( input, 255, stdin );

  input[strlen(input)-1] = '\0'; // overwrite \n with \0

  if ( strcmp( input, "exit" ) == 0 ) // shell command
    exit(0);
}
0 голосов
/ 03 июня 2018

char input[100];output[100];

Вы хотите:

char input[100], output[100];

Также добавьте: #include <fcntl.h>

В общем, man open (идругие функции, которыми вы пользуетесь) - ваш друг - он сообщает вам, что #include s добавить.

В вашем коде гораздо больше потенциальных ошибок и произвольных ограничений.Некоторые примеры:

void execute( char* str)
{
  char input[100], output[100];
  ...
  if(strcmp(args[i],"<")==0)
  {   
    args[i]=NULL;
    strcpy(input,args[i+1]);  // possible stack buffer overflow.

  if(strcmp(args[i],">")==0)
  {
    args[i]=NULL;
    strcpy(output,args[i+1]);  // possible stack buffer overflow


char** parse( char* str )
{
  char** args = malloc( 256 );  // limit of 256/sizeof(char*) parameters.
  // on a 64-bit system, if more than 32 parameters are supplied ...

         args[i] = strtok( NULL, " " );  // ... possible heap buffer overflow.


  fgets( input, 255, stdin );  // arbitrary limit of 254 characters on command line.

Нет гарантии, что строка заканчивается на \n:

  input[strlen(input)-1] = '\0'; // overwrite \n with \0

Если бы я оценивал эту «оболочку», я бы дал ей «F».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...