【问题标题】:Issue with libreadline when completing an upper case directory完成大写目录时出现 libreadline 问题
【发布时间】:2017-01-27 13:23:27
【问题描述】:

这是我正在创建的外壳的一部分。我在使用 libreadline 时遇到了一些问题,因为当 shell 被加载并且我尝试使用自动完成(所以按 TAB)在目录中 cd 时,在我按 enter 后我访问了目录,但是在打印另一个提示之前我得到了一些奇怪的输出.我注意到只有当目录名称以大写字母开头时才会发生这种情况。

示例:“user:: ~ % cd Github”

下一个提示是:“8b�/�user :: Github %” 我真的不明白为什么,这对我来说真的很奇怪。

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/wait.h>
#include <signal.h>
#include <readline/history.h>
#include <readline/readline.h>
#include "flush.h"
#include "env.h"
#include "fget.h"

char * flush_builtins[] =
{
  "cd",
  "help",
  "exit",
  "ver",
  "fget"
};

int flush_num_builtins() {
  return sizeof(flush_builtins) / sizeof(char *);
}

int (*flush_func[]) (char **) =
{
  &flush_cd,
  &help,
  &exit_flush,
  &ver,
  &fget
};

static int flush_startp(char **args)
{
  pid_t pid;
  int status;
  pid = fork();
  if (pid == 0)
  {
    if (execvp(args[0], args) == -1)
    {
      fprintf(stderr, "flush: command not found\n");
    }
    exit(1);
  }
  else if (pid < 0)
  {
    fprintf(stderr, "flush: command not found\n");
  }
  else
  {
    do
    {
      waitpid(pid, &status, WUNTRACED);
    } while (!WIFEXITED(status) && !WIFSIGNALED(status));
  }

  return 1;
}

static int flush_exec(char **args)
{
  int i;

  if (args[0] == NULL)
  {
    return 1;
  }

  for (i = 0; i < flush_num_builtins(); i++)
  {
    if (strcmp(args[0], flush_builtins[i]) == 0) {
      return (*flush_func[i])(args);
    }
  }

  return flush_startp(args);
}

static char * flush_read(void)
{
  fflush(stdout);
  char *line_read = malloc(sizeof(char) * LINE_BUF);
  char *prompt = malloc(sizeof(char) * LINE_BUF);
  char *current, buffer[TOK_BUF];
  current = getcwd(buffer, TOK_BUF);

  strcat(prompt, get_user());
  strcat(prompt, " :: ");

  if (strcmp(current, get_home()) == 0)
  {
    strcat(prompt, "~");
  }

  else
  {
    strcat(prompt, get_cwd());
  }

  strcat(prompt, " % ");
  line_read = readline(prompt);

  if (line_read && *line_read)
  {
    add_history(line_read);
  }

  return line_read;
  free(prompt);
  free(line_read);
  free(current);
}

static char **flush_getargs(char * line)
{
  int bufsize = TOK_BUF;
  int i = 0;
  char **tokens = malloc(bufsize * sizeof(char *));
  char **token;

  if (!tokens)
  {
    fprintf(stderr, "allocation error\n");
    exit(1);
  }

  token = strtok(line, DELIM);
  while (token != NULL)
  {
    tokens[i] = token;
    i++;
    token = strtok(NULL, DELIM);
  }

  tokens[i] = NULL;
  return tokens;
}


static void flush_loop(void)
{
  char *line;
  char **args;
  int  status;

  do
  {
    line = flush_read();
    args = flush_getargs(line);
    status = flush_exec(args);
    free(line);
    free(args);
  } while (status);
}

static void handler(int num)
{
  signal(SIGINT, handler);
  flush_loop();
  fflush(stdout);
}

int main()
{
  init();
  signal(SIGINT, handler);
  flush_loop();
  return 0;
}

【问题讨论】:

    标签: c shell readline


    【解决方案1】:

    您不能将strcat 与非\0 终止的字符串一起使用:

    char *prompt = malloc(sizeof(char) * LINE_BUF);
    char *current, buffer[TOK_BUF];
    current = getcwd(buffer, TOK_BUF);
    
    strcat(prompt, get_user());
    

    使用strcpy 代替strcat,或使用calloc 代替malloc

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-10-11
      • 2012-12-12
      • 2011-11-20
      • 1970-01-01
      • 2017-07-20
      • 1970-01-01
      • 2011-08-03
      相关资源
      最近更新 更多