For my OS class I have to create a terminal with different commands.
One task is to implement pipes.
I want to implement a ( env | sort ) command.
Is it possible? If yes, can someone help me?
The code for it is in the last else if(!strcmp(arr[0], "env")&& !strcmp(arr[1],"|") && arr[2]!="\0")
The code is larger but i posted just the part that interest me.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <string.h>
#include <errno.h>
#define MAX 256
char *comd = NULL;
size_t sizeLine = 0;
int i;
char *param;
char *arr[MAX];
/*From main() -> run() -> spawn child to run commands*/
void run(){
int pid = fork();
if (pid != 0) {
int s;
waitpid(-1, &s, 0); // Wait for child to close
}
else {
//Check if there wass an error
if(execvp(arr[0], arr) == -1){
perror("Wrong command / Command doesn't exists");
exit(errno);
}
}
}
/*From main() -> splitInput() -> write in arr[]*/
void splitInput(char *input){
i = 0;
param = strtok(input, "\n ");
while (param != NULL) {
arr[i ] = param; // Add param to arr
param = strtok(NULL, "\n ");
}
arr[i] = NULL;
}
void about() {
printf(" AUTHOR : TULCAN ANDRES \n");
printf(" EMAIL : [email protected]\n");
printf(" Code Language : C \n");
printf(" Commands avalabile : wc / expand / env / clear / exit / help ( or -h )\n");
}
int main(int argc, char *argv[]) {
system("clear");
printf("andres@andres-VirtualBox:~/Desktop$> ");
while(1)
{
//take input
getline(&comd, &sizeLine, stdin);
//Check input != empty
if(strcmp(comd,"\n")==0){
printf("andres@andres-VirtualBox:~/Desktop$> ");
continue;
}
//Split input
splitInput(comd);
//printf("%s, arr 1 : ",arr[1]);
//List commands
if(!strcmp(arr[0], "exit") || !strcmp(arr[0], "quit"))
return EXIT_SUCCESS;
else if(!strcmp(arr[0],"help") || !strcmp(arr[0],"-h")){
//MENU
printf("\n getversion - print author and project informmations.\n");
printf("\n wc - COMMAND \n");
printf("\n -c - print the characters number.");
printf("\n -w - print the word number.");
printf("\n -l - print the newline number.");
printf("\n -L - print the MAX. display width.\n");
printf("\n EXPAND - COMMAND \n");
printf("\n -t - have tabs N characters apart.");
printf("\n -i - dont convert tabs after non blanks.\n");
printf("\n ENV - COMMAND \n");
printf("\n -u - remove variable from the enviornment.");
printf("\n");
}
else if(!strcmp(arr[0], "env")&& !strcmp(arr[1],"|") && arr[2]!="\0")
{
if(!strcmp(arr[2],"sort"))
{
extern char ** environ;
char ** var;
char str[50]="ENV_FOR_PROJECT=456";
for(var=environ;*var!=NULL;var )
{
printf("\n %s", *var);
}
}
else printf("no");
}
else
run();
printf("andres@andres-VirtualBox:~/Desktop$> ");
}
printf("\n///////////////\nError occured. Prob bug!!!\n/////////////////\n");
return EXIT_FAILURE;
}
CodePudding user response:
Is there a way to sort alphabetically the env
Yes
Walk
environto find count of string pointersn.Allocate an array
nof string pointersconst char *a[n].Copy
environintoa.Sort
awithqsort().printf()the lista.Free any allocations.
CodePudding user response:
Is there a way to sort alphabetically the env
Of course.
extern char ** environ;
The variable environ points to an array of pointers to strings called the "environment". The last pointer in this array has the value NULL.
So you can think of it as char * environ[].
You don't want to write to this, so the first thing to do is to copy it -- for which you need to know how many entries there are.
size_t count = 0;
while ( environ[count] != 0 )
{
count;
}
Now reserve the amount of space required for your copy (which, note, does not end on a NULL pointer as the original, but you have a count of elements now so the NULL pointer is not needed)...
char ** my_environ = malloc( sizeof( char * ) * count );
...make the copy...
memcpy( my_environ, environ, sizeof( char * ) * count );
...which you can then sort:
qsort( my_environ, count, sizeof( char * ), comp );
You need a compare function:
int comp( void const * lhs, void const * rhs )
{
char const * l = *(char const **)lhs;
char const * r = *(char const **)rhs;
return strcmp( l, r );
}
And print:
for ( size_t i = 0; i < count; i )
{
puts( my_environ[i] );
}
