Run c program from another one using system gcc command - c

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

Related

Why does the system call system() not work as intended in this C program?

This is a C program that connects two prcoesses (the parent and child) to a pipe. The child process runs a python script that filters a phrase (String) in an RSS feed and the parent process captures the URL and opens it in a browser. This is the source code
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
void open_url(char *url)
{
char launch[255];
sprintf(launch, "cmd /c start %s", url);
system(launch);
}
void error_msg(char *msg)
{
printf("msg: %s\n", msg);
fprintf(stderr, "%s: %s\n", msg, strerror(errno));
exit(1);
}
int main(int argc, char* argv[])
{
char *phrase = argv[1];
char *vars[] = {"RSS_FEED=https://rss.app/feeds/tUpJh41L1MCpL3dl.xml", NULL};
int fd[2];
if(pipe(fd) == -1)
error_msg("Can't open a pipe");
pid_t pid;
pid = fork();
if (pid == -1)
error_msg("Can't fork process");
if (!pid)
{
dup2(fd[1], 1);
close(fd[0]);
if (execle(
"C:/Users/LENOVO/AppData/Local/Programs/Python/Python310/python",
"C:/Users/LENOVO/AppData/Local/Program/Python/Python310/python",
"./rssgossip.py", "-u", phrase, NULL, vars) == -1
)
error_msg("Can't run script");
}
dup2(fd[0], 0);
close(fd[1]);
char line[255];
while(fgets(line, 255, stdin))
{
if (line[0] == '\t')
open_url(line + 1);
}
return (0);
}
The program compiles without any errors, but when the parent calls system(launch) in open_url(), here's the issue. It surprisingly executes only the first part of the command stored in launch which is "cmd /c start" and ignores the url. More surprisingly is when I debugged the program through a simple printf statement, printf("%s", launch), I replaced the same output of the printf statement with the launch variable so instead of system(launch) -> system("cmd /c start 'url'") and it executed the url in a browser as intended.
EDIT: This is the direct downloading link of the python script (rssgossip.py) used in this program if you would like to try it to get what I'm trying to do clearer.
I recommend you running the script as a Python script first (with Python interpreter) to understand what actually this script does. To run it as a Python script, you would need to define RSS_FEED environment variable and assign an rss feed to it RSS_FEED=<rss_feed_url> (you can use the rss_feed_url used in this program) and finally run it as python rssgossip.py '<any_phrase>'
when i tried this code and it ran fine
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
void open_url(char *url)
{
char launch[255];
sprintf(launch, "cmd /c start "" %s", url);
printf("%s",launch);
system(launch);
}
int main()
{
char url[] = "C:/emu8086/emu8086.exe";
open_url(url);
}
may be the problem at parameter which you input

how to use execl to send a pointer as command line argument to another program

I am trying to accepts two integers (say low and high) as command line argument and in my main program is trying to call two other programs. program-1 should calculate the summation of all integers between (low, high) as sum_res and program-2 should evaluate whether sum_res is prime or not.
So I was trying to create two processes and I want to share a common variable between two processes but after execution I checked that only my main program is giving me segmentation fault.
I am new to this concept of execl please help:
My main program:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <string.h>
int sum_res=0;
int main(int argc, char *argv[])
{
int low = atoi(argv[1]), high = atoi(argv[2]);
pid_t pid;
if((pid=vfork())==0)
{
execl("pro1","pro1", low, high, &sum_res, (char *)NULL);
exit(0);
}
else if(pid > 0)
{
wait(NULL);
execl("pro2","pro2", sum_res, (char *)NULL);
exit(0);
}
return 0;
}
My program-1 is: (Named prog1.c and compiled as gcc -g prog1.c -o prog1)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
int n1 = atoi(argv[1]), n2 = atoi(argv[2]), i, sum_res = (int *)(argv[3]);
for(i=n1; i<=n2; i++)
{
(*sum_res)+=i;
}
printf("Sum is : %d\n", *sum_res);
return 0;
}
My program-2 is: (Named prog2.c and compiled as gcc -g prog2.c -o prog2 -lm)
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
int *main(int argc, char *argv[])
{
int sum_res = atoi(argv[1]), i, c=0;
for(i=2; i<=sqrt(sum_res); i++)
{
if(sum_res % i == 0)
{
c++;
break;
}
}
if(c==0)
{
printf("Prime \n");
}
else printf("Not Prime \n");
return 0;
}
Note: All 3 programs and their respective executables are present in the same current working directory.
If this is not possible then how will i get the summation result from program-1 into program-2 ?
It makes sense that you receive a segmentation fault. A pointer is a memory address inside a single process memory space. Each process memory space is completely independent and separated. This prevents one programs from accidentally breaking another program. When you try to read or write outside your process address space (the memory "segment" for your process) you receive a segmentation fault.
If you want to share memory space between two processes you need to use an IPC (Inter-process Communication) libraries to enable sharing memory space. One way is the shm_open function: https://www.geeksforgeeks.org/posix-shared-memory-api/

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.

Unix Processes - compile and run c program

Create a parent process that gets from the command line n arguments arg1, arg2, ... , argn. arg1 is the name to a source C, arg2 is the name of the executable file results from compile arg1, and arg3, ... , argn are arguments to start.
The parent compiles arg1 and creates the executable arg2, after that runs it into a son process.
I tried to solve the problem, using some examples, but I didn't really understand them, so the program is not working. I really need some help...
#include<unistd.h>
#include<stdio.h>
#include<sys/wait.h>
#include<string.h>
int main(int argc, char* argv[]){
char com[200];
int p;
p=fork();
strcpy(com,"gcc -o prog.c");
strcat(com,argv[1]);
if(p==0){
if(WEXITSTATUS(system(com))==0)
execl("./prog.c","./prog.c",argv[3],argv[4],argv[5],NULL);
}
wait(0);
exit(0);
return 0;
}
The C program I want to use, reads some input data from two files and stores data into another file.
This code more or less does what you say your program should do. In particular, it uses argv[2] as the program name. It uses snprintf() to avoid overflows with long arguments (but doesn't verify that it didn't overrun). It prints various status messages — partly as a debugging aid, partly to give meaning to the various parts of the program.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
int main(int argc, char* argv[])
{
int p;
if (argc != 6)
{
fprintf(stderr, "Usage: %s source program file1 file2 file3\n", argv[0]);
return(1);
}
if ((p = fork()) == 0)
{
char com[200];
snprintf(com, sizeof(com), "gcc -o %s %s", argv[2], argv[1]);
if (system(com) == 0)
{
printf("Compilation of %s successful\n", argv[2]);
fflush(0);
execl(argv[2], argv[2], argv[3], argv[4], argv[5], (char *)NULL);
fprintf(stderr, "Failed to execute %s\n", argv[2]);
return(1);
}
fprintf(stderr, "Compilation of %s from %s failed\n", argv[2], argv[1]);
return(1);
}
int status;
wait(&status);
printf("Compilation and execution of %s yielded status %d\n",
argv[2], WEXITSTATUS(status));
return 0;
}
When this file is named gc.c and is compiled to make gc, it can be run as:
$ ./gc gc.c ./gc2 gc.c gc.c gc.c
Compilation of ./gc2 successful
Usage: ./gc2 source program file1 file2 file3
Compilation and execution of ./gc2 yielded status 1
$
The usage message from gc2 is correct; the program expects 6 arguments, not the 4 it is given by the program.
You should look into the manual of exec which will tell you how to run exec to fork another process that behaves according to the specification. This code can help you how to pass on variables to a child process:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> /* for fork */
#include <sys/types.h> /* for pid_t */
#include <sys/wait.h> /* for wait */
int main()
{
/*Spawn a child to run the program.*/
pid_t pid=fork();
if (pid==0) { /* child process */
static char *argv[]={"echo","Foo is my name.",NULL};
execv("/bin/echo",argv);
exit(127); /* only if execv fails */
}
else { /* pid!=0; parent process */
waitpid(pid,0,0); /* wait for child to exit */
}
return 0;
}

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