Improve internal commands, improve icmd API

This commit is contained in:
Artur Tamborski 2018-12-23 02:29:55 +01:00
parent e1d4fa88ac
commit 251e88f324
2 changed files with 39 additions and 16 deletions

View File

@ -56,26 +56,37 @@ _icmd_die(int status, char *func, char *format, ...)
va_start(args, format);
if (status != 0)
printf("%s: Error: ", func);
vprintf(format, args);
if (status != 0)
putchar('!');
putchar('\n');
if (status < 0)
perror("Reason");
va_end(args);
}
int
call_icmd(int argc, char **argv)
find_icmd(char *cmd)
{
size_t i;
for (i = 0; i < ICMDS_SIZE; i++)
if (strncmp(g_icmds[i].cmd, argv[0], g_icmds[i].len) == 0)
return g_icmds[i].func(argc, argv);
/* I'm doing a len+1 here because I want to compare with NUL explicitly */
if (strncmp(g_icmds[i].cmd, cmd, g_icmds[i].len+1) == 0)
return i;
return INT_MAX;
return -1;
}
int
call_icmd(int idx, int argc, char **argv)
{
return g_icmds[idx].func(argc, argv);
}
@ -86,6 +97,8 @@ icmd_help(int argc, char **argv)
puts(
"\n psh - poor man's shell"
"\n written by: "
"\n Artur Tamborski "
"\n "
"\n internal commands: "
);
@ -114,9 +127,11 @@ icmd_echo(int argc, char **argv)
int
icmd_exit(int argc, char **argv)
{
puts("good bye!");
if (argc == 1)
exit(0);
exit(strtol(argv[1], NULL, 10));
return 0;
}
@ -155,7 +170,7 @@ icmd_cd(int argc, char **argv)
int
icmd_ls(int argc, char **argv)
{
char def_path[] = ".";
char def_path[] = "./";
char *path = def_path;
struct dirent *d;
DIR *dir;
@ -167,16 +182,23 @@ icmd_ls(int argc, char **argv)
do
{
if ((dir = opendir(path)) == NULL)
icmd_die(-1, "could not open directory '%s'", path);
icmd_die(-1, "Could not open directory '%s'", path);
/* print terminating slash if it wasn't given in argv */
printf("\n%s%c\n", path, (path[strlen(path)-1] != '/') ? '/' : '\0');
puts(path);
while ((d = readdir(dir)) != NULL)
/* don't print current directory '.' and parent directory '..' */
if (!(d->d_name[0] == '.' && (d->d_name[1] == '\0' || d->d_name[1] == '.')))
printf(" %s\n", d->d_name);
{
/* skip printing current directory '.\0' and parent directory '..\0' */
if (d->d_name[0] == '.' && (d->d_name[1] == '\0'
|| (d->d_name[1] == '.' && d->d_name[2] == '\0')))
continue;
printf(" %s%c\n", d->d_name, (d->d_type == DT_DIR) ? '/' : '\0');
}
closedir(dir);
putchar('\n');
closedir(dir);
path = argv[++i];
} while (i < argc);

View File

@ -3,7 +3,8 @@
/* API */
int call_icmd(int argc, char **argv);
int find_icmd(char *cmd);
int call_icmd(int idx, int argc, char **argv);
/* internal commands */