How to define system() - c

So I want to define system() function! Here is my function:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
void mySystem (char *command)
{
execlp (command, command, (char*) 0);
}
int main (int argc, char* argv[])
{
for (int i = 1; i < argc; i++)
{
char command[50];
strcpy(command, argv[i]);
mySystem(command);
}
return 0;
}
And then I try it and it is like that:
gcc exe6.c;
./a.out ls ls
In this case it only does one ls.
./a.out "ls -l"
In this case doesn't do anything. What am I doing wrong?

The man page actually tells you how to do it:
The system() library function uses fork(2) to create a child process that executes the shell command specified in command using execl(3) as follows:
execl("/bin/sh", "sh", "-c", command, (char *) 0);
system() returns after the command has been completed.

Related

Run c program from another one using system gcc command

I am trying to run a specific c program from my program using system in c.
gcc tell me "no such file or directory" even if i put the file
in the other program directory. The purpose is to execute the second program if some conditions are reached in the first. any help?
if(a==0){
system(" gcc -g -o iptablesExample mainiptables.c -lip4tc -lip6tc -ldl ");
system(" ./iptablesExample");
}
Maybe you can try your command with execve and fork, but I'm not sure it works
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <errno.h>
int main(int ac, char **av, char **env) {
pid_t pid = fork();
char *args[] = {"/usr/bin/ls", "-la", NULL}; //put the absolute path of gcc
if (pid == 0)
{
if (execve(args[0], args, env) == -1)
perror("error");
}
wait(&pid);
return 0;
}
Make sure to put the absolute path

C execvp won't execute the "ls -l" command but will execute "ls"

#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
int flag;
void catch (int sig)
{
if (sig == SIGINT){
flag = 1;
}
if (sig == SIGHUP){
flag == 2;
}
}
int main ()
{
int i;
char *nargs[40];
nargs[0] = "ls-l";
signal(SIGINT, catch);
signal(SIGHUP, catch);
i = 2;
while(i == 2){
if (flag == 1){
execvp(nargs[0],nargs);
}
if (flag ==2){
execvp(nargs[1],nargs);
}
}
return 0;
}
Here when nargs[0] is set to "ls-l" or "ls -l" it will not execute the command on SIGINT, but when nargs[0] is set to "ls" it will execute the command just fine. What am I doing wrong? The while loop condition is only the way that it is so that it will loop forever.
execvp() does not start a shell, it tries to find the binary you specify directly in the $PATH. So if you created an alias ls-l in your shell's startup scripts, then this won't work with execvp(). If you want that, use system() instead.
If you intended to execute ls -l, then you should do something like this:
const char *nargs[] = {"ls", "-l", NULL};
execvp(nargs[0], nargs);
Finally, if you really want to get a list of files, you don't need to call ls, you should use opendir()+readdir(), or alternatively ftw() on POSIX platforms.

Opening an application via C

I am trying to write a simple C PROGAM which EXECUTE a Python SCRIPT (and let it running...) and closes itself.
I tried the following commands but in both cases the C PROGRAM is still alive...
popen("sudo python /home/pi/main.py", "r");
system("sudo python /home/pi/main.py");
Thanks!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Edited !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
I tried this command based on your comments but no success:
char *argv[] = {"/home/pi/main.py"};
execv("sudo python", argv);
Anyone could help? Thanks!
!!!!!!!!!!! Edit 2 !!!!!!!!!!!!!!
This is how I compile it:
gcc -Wall restart.c -o safekill
This is the C program
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
my_popen(char cmd[])
{
FILE *fp;
char path[1035];
fp = popen(cmd, "r");
if (fp == NULL)
{
printf("Failed to run command\n");
exit(1);
}
//Read the output a line at a time - output it
while (fgets(path, sizeof(path)-1, fp) != NULL)
{
printf("%s", path);
}
pclose(fp);
}
int main()
{
my_popen("sudo killall python");
sleep(1);
my_popen("sudo killall raspivid");
sleep(1);
if(fork())
printf("Am I here?");
return 0;
char *file = "restart";
char *argv[] = {file, "-c", "sudo python main.py", NULL};
execvp(file, argv);
}
Result: It prints am I here and doesn't start the python.
It is so frustrating.... :-(
You need to add the filename of the program itself to the argument list (argv[0]) and terminate the argument list with a NULL pointer.
Example:
#include <stdlib.h>
#include <unistd.h>
int main() {
if(fork())
return 0;
char *file = "python";
char *argv[] = {file, "-c", "import time; time.sleep(5); print 'Hello'", NULL};
execvp(file, argv);
}
Expected behavior: Immediate (parent) program termination and a short Hello printed 5 seconds later by the child.
Maybe you need to workaround the sudo somehow, but this should get you started.

execl command to write on file

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define MAXLINE 512
main(int argc,char* argv[]){
int k;
for (k=0; k<argc; k++) {
if (k%2==0) {
if (fork()==0){
execl("/user/bin/rev","rev",argv[k],">",argv[k],NULL);
exit(1);
}
}
else
{
if (fork()==0){
execl("/usr/bin/awk","awk","-f","ouk.awk",argv[k],">",argv[k],NULL);
exit(1);
}
wait(0);
}
}
}
awk script
{ for (i=NF;i>=1;i--){ if(s){s=s" "$i} else{s=$i }}{print s;s=""}}
Could someone please tell why this does not work? What I am trying to do is modify
the file argv[i] using the awk script or the rev command
Thanks
To have piping (>) work a shell needs to be involved. The OP's code does not call a shell but starts the awk process directly.
You might like to replace this line:
execl("/usr/bin/awk","awk","-f","ouk.awk",argv[k],">",argv[k],NULL);
by those:
char cmd[PATHMAX] = "";
sprintf(cmd, "\"/usr/bin/awk -f out.awk %s > %s\"", argv[k], argv[k]);
execl("/bin/sh", "sh", "-c", cmd, (char *) NULL);
/* As execl() does not return if successful, getting here indicates an error! */
perror("execl() failed");
(This implies that the strings referenced by argv[k]do not contain spaces.)
For details please see your shell's man pages. Note that /bin/sh commonly is linked to some other shell program like bash.

Using execve() to write the ls program in UNIX

At a high level, how would you use the execve() function to write a duplicate of the ls program in UNIX? I am doing an exercise to familiarize myself with the exec() family of functions, command-line arguments, and environment variables. I am not familiar with using these concepts, however I know what they do.
The code below can excute ls command. Do you mean this?
#include <stdio.h>
int main(void)
{
system("ls");
return 0;
}
And I wrote a simple ls demo for you.
my_ls.c
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
int main(int argc, char *argv[])
{
if (argc != 2) {
return 0;
}
DIR *dir = opendir(argv[1]);
if (dir) {
struct dirent *s_dir;
while((s_dir = readdir(dir))) {
printf("%s ", s_dir->d_name);
}
printf("\n");
}
return 0;
}
Usage:
gcc my_ls.c -o my_ls
./my_ls .

Resources