No colour output if program run with exec - c

I have a C program that runs
execvp("grep", args);
Where args is an array {"grep", "test"} (test being the word I want grep to find).
The issue is that grep's output is not coloured. In a normal bash shell, grep highlights test in red, but in my program's output it just prints the line like
this is a test with no highlighting or colours of any sort.
I'm also using execvp to execute some other commands which also produce coloured output in a bash shell, and have no colours in my output.
Is there any way to fix this? Something I need to do to stdout?

You need to provide the correct option to grep in order to get it to colorize. Most likely, your shell environment includes:
alias grep='grep --color=auto'
but execvp knows nothing about aliases.
So create the args array: {"grep", "--color=auto", "test", 0} and use that in your execvp("grep", args); call.

Related

Using execvp with Input,Output and redirection

In a C program, let's say i wann use Exec functions for executing a given program, for example if i wanna just try ls -l i'll do something like
args[0]="ls";
args[1]="-l";
args[2]=NULL;
...
execvp("ls", args);
and it's all fine. Now what if i wanna also add the redirection to a file (or to stderr)?
I'm stuck, it's obvious that adding >log.txt as a 3rd entry in the array won't work, but I don't know how to proceed.
And also, what if I wanna pass some Input parameters? What if i wanna execute a GCC command like "gcc -o out in redirection>log.txt" ?
[update from comment:]
It's a C program that simulate a shell which can "run strings", string that contains a command, a list o parameters, input and a redirection.
Just set up your file descriptors as the exec-d process shall find them and then do the exec.
For that you need open, dup2 and close.
All functions in the exec-family just replace the current process with whatever one you say.
Run the command in a shell:
char * args[] = {
"sh",
"-c",
"ls -l >out.ls 2>err.ls <in.ls",
NULL
};
...
execvp(args[0], args);
perror("execvp() failed");

Can't get control back after execvp and wait()

I'm coding a small shell that must execute my commands that I parse.
f is a char** like this: [ls][-la]
p is the same, used like this: [wc]
So I tried to pipe ls -la in wc.
My probleme is that when I execute "ls -la | wc && date", which works well for the pipe, my minishell get closed and it doesn't execute "date". I used the wait function to wait for it to finish but doesn't do anything. Looks like it's stuck and exit just after the 2nd execvp.
My arrays ends well by NULL.
ls -la | wc is well executed but I get back to bash after this.
I've tried with execlp and execl but I think this is not the probleme considering that I need options of my first argument (ls + -la).
Could you help me please ?
Thanks in advance :)
All forms of exec never return; they replace the currently running image with the indicated executable. The key word here is "replace".
The only circumstance in which the statement following a call to exec* gets executed is if the exec fails (for example, if it cannot find the executable).

What does execvp actually do? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Writing a shell - how to execute commands
I've been tasked with writing a shell in C. So far I understand that execvp will try to run the program in arg1 with arg2 as parameters. Now it seems that doing this
execvp ("ls", args); //assume args is {"ls", ">", "awd.txt"}
is not equivalent to typing this in the console
ls > awd.txt
I realize that I need to use freopen to achieve the same results but I'm curious what execvp is doing.
The exec family of functions are ultimately a system call. System calls go straight into the kernel and typically perform a very specific service that only the kernel can do.
Redirection, on the other hand, is a shell feature.
So, when one types ls > awd.txt at a shell, the shell first does a fork(2), then it closes standard output in the child, then it opens awd.txt on file descriptor one so that it's the new standard output.
Then, and only then, the shell will make an exec-family system call.
In your case you simply passed the strings > and awd.txt to the exec system call, and from there to ls. BTW, be sure you terminate your execvp arg array with a null pointer.
Note: As you can see, the redirection operators are never seen by the executed program. Before Unix, directing output to a file had to be done by every program based on an option. More trivia: most programs never know they were redirected, but ironically, ls does check to see if its output is a tty, and if so, it does the multi-column formatted output thing.
It's executing ls with 2 arguments: > and awd.txt. It is equivalent to running:
'ls' '>' 'awd.txt'
You can pass your command directly to the shell:
char * const args[] = { "sh", "-c", "ls > awd.txt", NULL};
execvp("/bin/sh", args);
But it doesn't seems like a good idea.

using exec to sort a text file in c

I have a text file full of records (output.txt) and I want to sort every record by its id. After the sorting the sorted records are written into a new file (sorted.txt).
To do that I am using bash's command "sort" via an execl() function. To check the validity of my sort command, I wrote the same command straight into the bash and the result is the expected one. But when I try to use the execl command through my C program, most of the time the answer will be that there is not a file /usr/bin/sort (I am using Mac OSX) or no error message will be thrown but nevertheless nothing happens...
What I am using is this:
execl("/usr/bin/sort", "usr/bin/sort", "-n","-k", "1", "-u", "output.txt", ">", "sorted.txt", (char*)NULL);
or this
execl("/usr/bin/sort", "usr/bin/sort", "-n","-k", "1", "-u", "-o", "sorted.txt", "output.txt", (char*)NULL);
I know that both of these 2 sort commands are correct when I m using them in the bash. What happens to C?
Thnx all in advance!
Output redirection (> somefile.txt) is a feature of the shell, not the sort program (which AFAIK is not a bash built-in).
The exec family of functions doesn't start the shell, only the program you've specified.
If you don't know the path to the program, you can use the functions with p in their names (execlp in your case, I think) and just give them "sort" as program name, they'll search for it in $PATH like bash does.
Alternatively you can try system("sort output.txt > sorted.txt"). The system function's behaviour is implementation dependent though on linux it basically spawns a new shell which executes the command passed to it. system(ARG) is equivalent to sh -c ARG. The redirection will work if the shell supports it in your system's implementation of the system function.

command injection in C programming

I was implementing an echo command using the system() function. The argument for the echo command comes from a command line argument. But when used ';' in the argument it is showing the directory listing.
What should i do to avoid it? Is it because of command injection in my program?
update: code added from comment
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char **argv) {
char cmd[50] = "echo ";
strcat(cmd,argv[1]);
system(cmd);
}
I could compile the code but while executing if i give the command line argument as eg: './a.out hello;ls ' then directory listing is happening.
Why are you trying to use a shell access (which is exactly what System() does), and than attempt to restrict it?
If you need for some reason to use 'echo', please build your own execve() parameters, and launch /bin/echo directly.. this way you can restrict the damage only to the tasks 'echo' can do.
When attempting to run your program with the command ./a.out hello;ls, you are actually providing the shell with two separate commands that it executes in sequence. First the shell runs a.out with the command line parameter "hello" in argv[1], which prints it out using echo. Then your program exits, and the shell runs the next command, ls, and displays the directory listing.
If you want to pass that string to the program as a command line parameter, you need to escape the special shell character ;, so the shell does not parse it before giving it to your program. To escape a character, precede it with a \.
Try running the command with ./a.out hello\;ls, and then using printf instead of echo.
[can't respond to other answers yet, so reposting the question]
"Is possible to get the argument with ';', without using '\' in the command line argument. Is possible for me to include a '\' from my program after getting argv?"
No, it is not possible. The interpretation of ";" is done by the shell before getting to your program, so unless you escape at the call, your program will never be aware of the ";". i.e.
PROG1 parms ; PROG2
will cause the shell (which is interpreting what you type) to do the following:
start PROG1 and pass it parms.
once PROG1 is done, start PROG2
There are a number of special characters which the shell will take over by default and your program will never see: * for wildcards, | for pipes, & for parallel execution, etc... None of these will be seen by the program being run, they just tell the shell to do special things.
Alternatively to using the "\", you can enclose your parameter in single or double quotes (which are different, but for your example will both work). i.e.:
./a.out "hello;ls"
./a.out 'hello;ls'
Note that these will work for the printf option, if you call "system" you are in effect telling C to start a shell to run what you are passing in, so the input will once again be subject to shell interpretation.
system() is very difficult to use in a secure manner. It's much easier to just use one of the exec* functions.

Resources