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

int lsh_launch(char **args)
{
  pid_t pid, wpid;
  int status;
  pid = fork();
  if (pid == 0)
  {
    //принимаем имя и массив аргументов
    if (execvp(args[0], args) == -1)
    {                                     //первое слово массива определяем как команду, остальные аргументы
      perror("lsh");                      //abcd-команда. fddeh,egf-аргументы
    }
    exit(EXIT_FAILURE);
  } else if (pid < 0)
  {
    // ошибка в создании
    perror("lsh");
  } else
  {
    do
    {      //ну а если все хорошо, то ждем ее завершения
      wpid = waitpid(pid, &status, WUNTRACED);
    }
    while (!WIFEXITED(status) && !WIFSIGNALED(status));
  }
  return 1;
}

int lsh_execute(char **args)
{
  return lsh_launch(args);
}

#define LSH_RL_BUFSIZE 1024
char *lsh_read_line()
{
  int bufsize = LSH_RL_BUFSIZE;
  int position = 0;
  char *buffer = malloc(sizeof(char) * bufsize);
  char c;
  if (!buffer)
  {
    fprintf(stderr, "lsh: Ошибка памяти\n");
    exit(EXIT_FAILURE);
  }
  while (((c=getchar())!=EOF)||(c!='\n'))
  {
    //при EOF или \n обнуляем буффер и возвращаем его значение
      buffer[position] = c;
      position++;                                   //должны ввести с ввода и заполнить массив
      printf("%s",buffer);                               //то есть получаем строку abcd fddeh egf
      if (position >= bufsize)
      {
        bufsize += LSH_RL_BUFSIZE;
        buffer = realloc(buffer, bufsize);          //расширяем если не хватило
        if (!buffer)
        {
          fprintf(stderr, "lsh: Ошибка памяти\n");
          exit(EXIT_FAILURE);
        }
      }
  }
  buffer[position] = '\0';
  printf("%s",buffer);
  return buffer;
}

#define LSH_TOK_BUFSIZE 100
char **lsh_split_line(char *line)
{
  printf("%d",1);
  int bufsize0 = LSH_TOK_BUFSIZE;
  int bufsize = LSH_TOK_BUFSIZE, position = 0;
  char **tokens = malloc(bufsize * sizeof(char*));
  int flag = 0;//определение кавычек
  int pos = 0;
  char ch = 0;
  printf("А тут line%s",line);
  while ((ch!=EOF)||(ch!='\n'))         //приравнием ch строку посимвольно
  {
    ch = line[pos];
    printf("%c",ch);
    if ((ch=='\"')&&(flag==1)) flag = 0;            //дожен выйти массив tokens[0]=abcd; tokens[1]=fddeh; tokens[2]=egf
    if ((ch=='\"')&&(flag==0)) flag = 1;
    if ((ch!=' ')||((ch==' ')&&(flag = 1)))
    {
      tokens[position][pos] = ch;
      pos++;
    }
    else
    {
    printf("\n");
    printf("%s",tokens[position]);
    position++;
    }
  if (position >= bufsize) {                            //расширяем если не хватило строк или пасяти для строк то выделяем
   bufsize += LSH_TOK_BUFSIZE;
   tokens = realloc(tokens, bufsize * sizeof(char*));
   if (!tokens) {
     fprintf(stderr, "lsh: Ошибка памяти\n");
     exit(EXIT_FAILURE);
   }
  }
 if (pos >= bufsize0)
 {
  bufsize0 += LSH_TOK_BUFSIZE;
  tokens[position] = realloc(tokens[position], bufsize0 * sizeof(char*));
  if (!tokens)
  {
    fprintf(stderr, "lsh: Ошибка памяти\n");
    exit(EXIT_FAILURE);
  }
 }
 }
 tokens[position] = NULL;
 return tokens;
}


void lsh_loop(void)
{
  char *line;
  char **args;
  int status;

  do
  {
    printf("> ");                 //приглашаем
    line = lsh_read_line();       //функция чтения входной строки
    args = lsh_split_line(line);  //разбиение
    status = lsh_execute(args);   //выполнение

    free(line);                   //очистка
    free(args);
  } while (status);
}

int main(int argc, char **argv)
{
  //загрузка файлов если они есть и запуск команд
  lsh_loop();
  return EXIT_SUCCESS;
}
