Reputation: 163
I want to create a program msh that will recognize some other C programs I wrote and spawn a new process for that C program and run it.
For example I have already written my own copy, move, and remove functions named mycopy, myremove, and mymove.
I want to be able to do ./msh mycopy file1 file2 And have msh spawn off a new process and run mycopy and perform the action, and wait for that child process to finish before exiting.
I tried what you see below and it compiles but doesn't seem to actually perform the tasks. Any suggestions? I've never used fork(), execl() or wait() before so I may have missed and include or parameter, please correct me if I'm wrong.
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
int main(int argc, char* argv[]){
int pid;
if(strcmp(argv[1], "mycopy") == 0){
if(pid = fork() == 0){
execl("/home/1234/mycopy", argv[2], argv[3]);
}
}
if(strcmp(argv[1], "myremove") == 0){
if(pid = fork() == 0){
execl("/home/1234/myremove", argv[2]);
}
}
if(strcmp(argv[1], "mymove") == 0){
if(pid = fork() == 0){
execl("/home/1234/mymove", argv[2], argv[3]);
}
}
if(pid > 0){
wait((int*)0);
}
return 0;
}
I tried this and working 3 printed twice. Does that mean my execl command is broken and if so how would I fix it since argv[2] and argv[3] need to be passed down to ./mycopy
int pid = fork();
if(strcmp(argv[1], "mycopy") == 0){
if(pid == 0){
printf("WORKING1");
execl("/home/1234/mycopy", argv[2], argv[3]);
printf("WORKING2");
}
}
wait((int*)0);
printf("WORKING3");
return 0;
Upvotes: 1
Views: 2130
Reputation: 5256
Forking always seems to be a bit of a mindbender for newcomers. What actually happens is that when you return from fork()
you now have two processes (parent and child), both of which have just returned from fork()
and both of which are about to execute the next statement.
The usual idiom is to call int child_pid = fork()
and then test child_pid
to determine if I am the child process (child_pid == 0
) or the parent process (child_pid != 0
) and carry on either exec()
ing or wait()
ing as appropriate.
You have not made this test; both of your processes are trying to carry out both behaviours.
That should be enough to get you on the right track.
EDIT: I just compiled the following:
/**
* @file msh.c
* @brief fork/execl example
*/
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
int main(int argc, char* argv[])
{
int pid;
if ((pid = fork()) == 0)
{
if(strcmp(argv[1], "mycopy") == 0)
{
{
execl("./hello", "./hello", argv[2], argv[3], NULL);
}
}
if(strcmp(argv[1], "myremove") == 0)
{
{
execl("./hello", "./hello", argv[2], NULL);
}
}
if(strcmp(argv[1], "mymove") == 0)
{
{
execl("./hello", "./hello", argv[2], argv[3], NULL);
}
}
}
else
{
wait(NULL);
}
return 0;
}
(edited again) and
/**
* @file hello.c
* @brief test load for msh
*/
#include <stdio.h>
int main(int argc, char* argv[])
{
int i;
for (i = 0; i < argc; i++)
printf("Argc[%d] = %s\n", i, argv[i]);
return 0;
}
and it works, so perhaps the problem is in your child code?
I did notice that execl()
passes its second argument as the child's argv[0]
, so that might be causing you problems.
Upvotes: 2