Skip to content

Instantly share code, notes, and snippets.

@ramlaxman
Forked from Krush206/README.md
Last active June 1, 2023 12:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ramlaxman/69d732f435613f5ac476ba2bd995899a to your computer and use it in GitHub Desktop.
Save ramlaxman/69d732f435613f5ac476ba2bd995899a to your computer and use it in GitHub Desktop.
A basic command interpreter. (For teaching purposes.)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
void my_system(char **);
int my_builtins(char *);
int main(void)
{
unsigned int i, j, arr_count;
char c, *cmd, **cmd_args;
while(printf("> "))
{
arr_count = (int) (cmd = (char *) (cmd_args = (char **) 0));
for(i = 0; (c = getchar()) != '\n'; i++)
{
if(!cmd)
{
if(!(cmd = (char *) malloc(1))) goto err;
*cmd = c;
continue;
}
if(!(cmd = (char *) realloc(cmd, i + 1))) goto err;
cmd[i] = c;
}
if(cmd)
{
cmd = (char *) realloc(cmd, i + 1);
cmd[i] = 0;
}
else continue;
for(i = 0; cmd[i]; i++)
{
if(cmd[i] != ' ')
{
for(j = 0; cmd[i] && cmd[i] != ' '; j++)
i++;
if(!cmd_args)
{
if(!(cmd_args = (char **) malloc(sizeof(char *)))) goto err;
}
else if(!(cmd_args = (char **) realloc(cmd_args, sizeof(char *) * (arr_count + 1)))) goto err;
cmd_args[arr_count] = (char *) malloc(j + 1);
snprintf(cmd_args[arr_count++], j + 1, "%s", cmd + i - j);
}
if(!cmd[i])
{
if(!(cmd_args = (char **) realloc(cmd_args, sizeof(char *) * (arr_count + 1)))) goto err;
cmd_args[arr_count] = (char *) 0;
break;
}
}
switch(my_builtins(*cmd_args))
{
case 1:
exit(0);
case 2:
if(!cmd_args[1])
{
if(chdir(getenv("HOME")) < 0)
fprintf(stderr, "chdir: Cannot change to HOME.\n");
}
else if(chdir(cmd + strlen(*cmd_args) + 1) < 0)
fprintf(stderr, "chdir: Cannot change to %s.\n", cmd + strlen(*cmd_args) + 1);
break;
default:
my_system(cmd_args);
}
for(i = 0; cmd_args[i]; i++)
free(cmd_args[i]);
free(cmd_args);
free(cmd);
}
return 0;
err:
fprintf(stderr, "Failed to allocate memory.\n");
return -1;
}
void my_system(char **param)
{
if(fork()) wait(NULL);
else if(execvp(*param, param) < 0)
{
fprintf(stderr, "%s: Command not found.\n", *param);
exit(0);
}
}
int my_builtins(char *param)
{
int i, ret = 0;
for(i = 0; param[i] && "exit"[i]; i++)
{
if(param[i] == "exit"[i]) ret++;
else
{
ret = 0;
break;
}
}
if(strlen(param) == ret && strlen("exit") == ret) return ret = 1;
else for(i = 0; param[i] && "chdir"[i]; i++)
{
if(param[i] == "chdir"[i]) ret++;
else
{
ret = 0;
break;
}
}
if(strlen(param) == ret && strlen("chdir") == ret) return ret = 2;
else return ret = 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment