Psst.. new poll here.
Psst.. new forums here.
Microsoft is blocking us again (TY IP Reputation!) so just use oauth login instead. :)
Paste
Pasted as C by Flo ( 15 years ago )
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#define INPUTBUFFER_INITIAL_CAPACITY 0x100
#define ARGV_INITIAL_CAPACITY 0x10
#define CRITICAL_ERROR(x) { printf(x); exit(1); }
/* A dynamic implementation of readline(), which I don't use as it is a
GNU extension and no part of the Ansi-C standard.
This function basically reads data from stdin until encountering a newline
and returns an allocated buffer which shall be freed by the caller */
static char* read_input()
{
char cur; /* Most recently read char from stdin */
char* buf; /* Buffer to store bytes read from stdin */
unsigned int buflen; /* Length of the allocated buffer */
unsigned int put = 0; /* Current put position of the buffer */
/* Allocate buffer */
buf = malloc(INPUTBUFFER_INITIAL_CAPACITY);
if(!buf)
CRITICAL_ERROR("read_input() : malloc error.");
buflen = INPUTBUFFER_INITIAL_CAPACITY;
/* Loop reading characters from stdin until encountering newline */
while( (cur = getchar()) != '\n')
{
/* If we reached capacity, double buffersize */
if(put >= buflen - 1) /* -1 because we need to store a nullbyte */
{
buf = realloc(buf, buflen * 2);
if(!buf)
CRITICAL_ERROR("read_input() : realloc error.");
buflen *= 2;
}
/* Append character to buffer */
buf[put++] = cur;
}
/* We are done, append nullbyte and return */
buf[put] = 0;
return buf;
}
/* This function parses an input string and generates argument vector and
argument count for them.
The buffer returned shall be freed by the caller */
char** parse_args(char* data, int* out_argc)
{
char** buf; /* Buffer to store argv items */
unsigned int buflen; /* Length of the allocated buffer */
unsigned int put = 0; /* Current put position of the buffer */
char* token; /* Stores an extracted token */
/* Allocate buffer */
buf = malloc(ARGV_INITIAL_CAPACITY * sizeof(char*));
if(!buf)
CRITICAL_ERROR("parse_args() : malloc error.");
buflen = ARGV_INITIAL_CAPACITY;
/* Extract first argument and add it to buffer */
token = strtok(data, " ");
buf[put] = malloc(strlen(token) + 1); /* +1 for nullbyte */
strcpy(buf[put], token);
++put;
*out_argc = 1;
/* Extract further arguments */
while( (token = strtok(NULL, " ")) != NULL)
{
/* If we reached capacity, double buffersize */
if(put >= buflen - 1) /* -1 because we need to store a nullbyte */
{
buf = realloc(buf, buflen * sizeof(char*) * 2);
if(!buf)
CRITICAL_ERROR("parse_args() : realloc error.");
buflen *= 2;
}
/* Add argument to buffer */
buf[put] = malloc(strlen(token) + 1); /* +1 for nullbyte */
strcpy(buf[put], token);
++put;
++(*out_argc);
}
/* We are done, append nullptr (for execvp) and return */
buf[put] = NULL;
return buf;
}
/* Function freeing buffer returned by parse_args */
void free_ptrvector(char** vec, int size)
{
int i; /* Index into the vector */
/* Free every single item */
for(i = 0; i < size; ++i)
free(vec[i]);
/* Free storage */
free(vec);
}
int main(int argc, char** argv)
{
char* input; /* Input read from stdin */
char** avector; /* Parsed arguments */
int acount; /* Amount of parsed arguments */
int pid; /* fork() return value */
/* Loop until an error occurs */
while(1)
{
/* Print prompt :) */
printf("Mastershell > ");
/* Retrieve data from stdin, parse it and free input buffer */
input = read_input();
avector = parse_args(input, &acount;);
free(input);
/* Fork! */
if( (pid = fork()) == -1)
{
/* -1 means fork() failed !
Free buffer and exit */
free_ptrvector(avector, acount);
CRITICAL_ERROR("fork() failed.");
}
else if(pid == 0)
{
/* Child !
execvp() and pass all passed arguments */
if(execvp(avector[0], avector) == -1)
{
/* execvp() returned, so an error occurred !
Free buffer and exit */
free_ptrvector(avector, acount);
CRITICAL_ERROR("execvp() failed.")
}
}
else
{
/* Parent !
Wait until child terminates */
errno = 0;
if(wait(pid) != pid)
{
/* -1 means wait() failed !
Free buffer and exit */
int error = errno;
printf("%d", error);
free_ptrvector(avector, acount);
CRITICAL_ERROR("wait() failed.")
}
free_ptrvector(avector, acount);
}
}
}
Revise this Paste