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); va_start(args, format);
if (status != 0) if (status != 0)
printf("%s: Error: ", func); printf("%s: Error: ", func);
vprintf(format, args); vprintf(format, args);
if (status != 0) if (status != 0)
putchar('!'); putchar('!');
putchar('\n'); putchar('\n');
if (status < 0) if (status < 0)
perror("Reason"); perror("Reason");
va_end(args); va_end(args);
} }
int int
call_icmd(int argc, char **argv) find_icmd(char *cmd)
{ {
size_t i; size_t i;
for (i = 0; i < ICMDS_SIZE; i++) for (i = 0; i < ICMDS_SIZE; i++)
if (strncmp(g_icmds[i].cmd, argv[0], g_icmds[i].len) == 0) /* I'm doing a len+1 here because I want to compare with NUL explicitly */
return g_icmds[i].func(argc, argv); 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( puts(
"\n psh - poor man's shell" "\n psh - poor man's shell"
"\n written by: "
"\n Artur Tamborski "
"\n " "\n "
"\n internal commands: " "\n internal commands: "
); );
@ -114,9 +127,11 @@ icmd_echo(int argc, char **argv)
int int
icmd_exit(int argc, char **argv) icmd_exit(int argc, char **argv)
{ {
puts("good bye!"); if (argc == 1)
exit(0); exit(0);
exit(strtol(argv[1], NULL, 10));
return 0; return 0;
} }
@ -155,7 +170,7 @@ icmd_cd(int argc, char **argv)
int int
icmd_ls(int argc, char **argv) icmd_ls(int argc, char **argv)
{ {
char def_path[] = "."; char def_path[] = "./";
char *path = def_path; char *path = def_path;
struct dirent *d; struct dirent *d;
DIR *dir; DIR *dir;
@ -167,16 +182,23 @@ icmd_ls(int argc, char **argv)
do do
{ {
if ((dir = opendir(path)) == NULL) 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) 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] == '.'))) /* skip printing current directory '.\0' and parent directory '..\0' */
printf(" %s\n", d->d_name); 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'); putchar('\n');
closedir(dir);
path = argv[++i]; path = argv[++i];
} while (i < argc); } while (i < argc);

View File

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