Sambho
asked on
About system call and managing processes in linux
Hi guys,
I got this program written in c and I am running on linux but I have difficulty in understanding on what this program is doing. Moreover, I don't know what kind of command line input should be given after running this program....
So, guys can you help me what kind of input should be given and basic understanding of the result it is giving.........
It would be nice if I get brief insight on this program.....
Tons of thanks in advance guys......
I got this program written in c and I am running on linux but I have difficulty in understanding on what this program is doing. Moreover, I don't know what kind of command line input should be given after running this program....
So, guys can you help me what kind of input should be given and basic understanding of the result it is giving.........
It would be nice if I get brief insight on this program.....
Tons of thanks in advance guys......
/* LIBRARY SECTION */
#include <ctype.h> /* Character types */
#include <stdio.h> /* Standard buffered input/output */
#include <stdlib.h> /* Standard library functions */
#include <string.h> /* String operations */
#include <sys/types.h> /* Data types */
#include <sys/wait.h> /* Declarations for waiting */
#include <unistd.h> /* Standard symbolic constants and types */
#include "smp1_tests.h" /* Built-in test system */
/* DEFINE SECTION */
#define SHELL_BUFFER_SIZE 256 /* Size of the Shell input buffer */
#define SHELL_MAX_ARGS 8 /* Maximum number of arguments parsed */
/* VARIABLE SECTION */
enum { STATE_SPACE, STATE_NON_SPACE }; /* Parser states */
int imthechild(const char *path_to_exec, char *const args[])
{
return execv(path_to_exec, args) ? -1 : 0;
}
void imtheparent(pid_t child_pid, int run_in_background)
{
int child_return_val, child_error_code;
/* fork returned a positive pid so we are the parent */
fprintf(stderr,
" Parent says 'child process has been forked with pid=%d'\n",
child_pid);
if (run_in_background) {
fprintf(stderr,
" Parent says 'run_in_background=1 ... so we're not waiting for the child'\n");
return;
}
wait(&child_return_val);
/* Use the WEXITSTATUS to extract the status code from the return value */
child_error_code = WEXITSTATUS(child_return_val);
fprintf(stderr,
" Parent says 'wait() returned so the child with pid=%d is finished.'\n",
child_pid);
if (child_error_code != 0) {
/* Error: Child process failed. Most likely a failed exec */
fprintf(stderr,
" Parent says 'Child process %d failed with code %d'\n",
child_pid, child_error_code);
}
}
/* MAIN PROCEDURE SECTION */
int main(int argc, char **argv)
{
pid_t shell_pid, pid_from_fork;
int n_read, i, exec_argc, parser_state, run_in_background;
/* buffer: The Shell's input buffer. */
char buffer[SHELL_BUFFER_SIZE];
/* exec_argv: Arguments passed to exec call including NULL terminator. */
char *exec_argv[SHELL_MAX_ARGS + 1];
/* Entrypoint for the testrunner program */
if (argc > 1 && !strcmp(argv[1], "-test")) {
return run_smp1_tests(argc - 1, argv + 1);
}
/* Allow the Shell prompt to display the pid of this process */
shell_pid = getpid();
while (1) {
/* The Shell runs in an infinite loop, processing input. */
fprintf(stdout, "Shell(pid=%d)> ", shell_pid);
fflush(stdout);
/* Read a line of input. */
if (fgets(buffer, SHELL_BUFFER_SIZE, stdin) == NULL)
return EXIT_SUCCESS;
n_read = strlen(buffer);
run_in_background = n_read > 2 && buffer[n_read - 2] == '&';
buffer[n_read - run_in_background - 1] = '\n';
/* Parse the arguments: the first argument is the file or command *
* we want to run. */
parser_state = STATE_SPACE;
for (exec_argc = 0, i = 0;
(buffer[i] != '\n') && (exec_argc < SHELL_MAX_ARGS); i++) {
if (!isspace(buffer[i])) {
if (parser_state == STATE_SPACE)
exec_argv[exec_argc++] = &buffer[i];
parser_state = STATE_NON_SPACE;
} else {
buffer[i] = '\0';
parser_state = STATE_SPACE;
}
}
/* run_in_background is 1 if the input line's last character *
* is an ampersand (indicating background execution). */
buffer[i] = '\0'; /* Terminate input, overwriting the '&' if it exists */
/* If no command was given (empty line) the Shell just prints the prompt again */
if (!exec_argc)
continue;
/* Terminate the list of exec parameters with NULL */
exec_argv[exec_argc] = NULL;
/* If Shell runs 'exit' it exits the program. */
if (!strcmp(exec_argv[0], "exit")) {
printf("Exiting process %d\n", shell_pid);
return EXIT_SUCCESS; /* End Shell program */
} else if (!strcmp(exec_argv[0], "cd") && exec_argc > 1) {
/* Running 'cd' changes the Shell's working directory. */
/* Alternative: try chdir inside a forked child: if(fork() == 0) { */
if (chdir(exec_argv[1]))
/* Error: change directory failed */
fprintf(stderr, "cd: failed to chdir %s\n", exec_argv[1]);
/* End alternative: exit(EXIT_SUCCESS);} */
} else {
/* Execute Commands */
/* Try replacing 'fork()' with '0'. What happens? */
pid_from_fork = fork();
if (pid_from_fork < 0) {
/* Error: fork() failed. Unlikely, but possible (e.g. OS *
* kernel runs out of memory or process descriptors). */
fprintf(stderr, "fork failed\n");
continue;
}
if (pid_from_fork == 0) {
return imthechild(exec_argv[0], &exec_argv[0]);
/* Exit from main. */
} else {
imtheparent(pid_from_fork, run_in_background);
/* Parent will continue around the loop. */
}
} /* end if */
} /* end while loop */
return EXIT_SUCCESS;
} /* end main() */
ASKER
Thank you phoffric,
but still I am not getting it... I am going through the program..I know there are lots of questions to be asked in the program. Can you tell me what is this program in overall trying to do.......
I compile shell executable and......
The result of the program is something like this...
$ ./shell
Shell(pid=593)> -test
Parent says 'child process has been forked with pid=594'
Parent says 'wait() returned so the child with pid=594 is finished.'
Parent says 'Child process 594 failed with code 255'
Shell(pid=593)> 23
Parent says 'child process has been forked with pid=600'
Parent says 'wait() returned so the child with pid=600 is finished.'
Parent says 'Child process 600 failed with code 255'
what does this result actually mean? Does the child process always gets finished instantly after getting forked and why is child process always failing with code 255.....
I have attached the smp1.tests.c
Thank You very much in advance.....
but still I am not getting it... I am going through the program..I know there are lots of questions to be asked in the program. Can you tell me what is this program in overall trying to do.......
I compile shell executable and......
The result of the program is something like this...
$ ./shell
Shell(pid=593)> -test
Parent says 'child process has been forked with pid=594'
Parent says 'wait() returned so the child with pid=594 is finished.'
Parent says 'Child process 594 failed with code 255'
Shell(pid=593)> 23
Parent says 'child process has been forked with pid=600'
Parent says 'wait() returned so the child with pid=600 is finished.'
Parent says 'Child process 600 failed with code 255'
what does this result actually mean? Does the child process always gets finished instantly after getting forked and why is child process always failing with code 255.....
I have attached the smp1.tests.c
Thank You very much in advance.....
#define _GNU_SOURCE
#include <stdio.h>
#undef _GNU_SOURCE
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "testrunner.h"
#include "smp1_tests.h"
#define quit_if(cond) do {if (cond) exit(EXIT_FAILURE);} while(0)
/* Prepare input, reroute file descriptors, and run the program. */
void run_test(const char *input, int argc, char **argv)
{
/* Prepare input */
FILE *in = fopen("smp1.in", "w");
fprintf(in, input);
fclose(in);
/* Reroute standard file descriptors */
freopen("smp1.in", "r", stdin );
freopen("smp1.out", "w", stdout);
freopen("smp1.err", "w", stderr);
/* Run the program */
quit_if(main(argc, argv) != EXIT_SUCCESS);
fclose(stdout);
fclose(stderr);
}
/* P5.1: Test of executing commands in the path */
int test_path(int argc, char **argv)
{
char *args[] = { "./shell", NULL };
FILE *out, *err;
int pid_tmp;
/* Run the test */
run_test("ls\n/bin/ls\nexit\n", 1, args);
/* Check output */
err = fopen("smp1.err", "r");
quit_if(fscanf(err, " Parent says 'child process has been forked with pid=%d'\n"
" Parent says 'wait() returned so the child with pid=%d is finished.'\n"
" Parent says 'child process has been forked with pid=%d'\n"
" Parent says 'wait() returned so the child with pid=%d is finished.'\n",
&pid_tmp, &pid_tmp, &pid_tmp, &pid_tmp) != 4);
quit_if(!feof(err));
fclose(err);
return EXIT_SUCCESS;
}
/* P5.2: Test of command line counter */
int test_counter(int argc, char **argv)
{
char *args[] = { "./shell", NULL };
FILE *out, *err;
int pid_tmp;
/* Run the test */
run_test("\n/bin/true\nexit\n", 1, args);
/* Check output */
out = fopen("smp1.out", "r");
quit_if(fscanf(out, "Shell(pid=%d)1> Shell(pid=%d)1> Shell(pid=%d)2> Exiting process %d\n", &pid_tmp, &pid_tmp, &pid_tmp, &pid_tmp) != 4);
quit_if(!feof(out));
fclose(out);
return EXIT_SUCCESS;
}
/* P5.3: Test of re-executing earlier commands */
int test_rerun(int argc, char **argv)
{
char *args[] = { "./shell", NULL };
FILE *out, *err;
int pid_tmp;
/* Run the test */
run_test("/bin/echo test\n!1\nexit\n", 1, args);
/* Check output */
out = fopen("smp1.out", "r");
quit_if(fscanf(out, "Shell(pid=%d)1> test\nShell(pid=%d)2> test\nShell(pid=%d)3> Exiting process %d\n", &pid_tmp, &pid_tmp, &pid_tmp, &pid_tmp) != 4);
quit_if(!feof(out));
fclose(out);
return EXIT_SUCCESS;
}
/* P5.5: Test of depth-limited sub */
int test_sub(int argc, char **argv)
{
char *args[] = { "./shell", NULL };
FILE *out, *err;
int pids[4], warned_too_deep;
/* Run the test */
run_test("sub\nsub\nsub\nexit\nexit\nexit\n", 1, args);
/* Check output */
out = fopen("smp1.out", "r");
err = fopen("smp1.err", "r");
/* First, check that the subshells were invoked. */
fscanf(out, "Shell(pid=%d)1> Shell(pid=%d)1> Shell(pid=%d)1> Shell(pid=%d)2> ", &pids[0], &pids[1], &pids[2], &pids[3]);
quit_if(!((pids[0] != pids[1]) && (pids[1] != pids[2]) && (pids[0] != pids[2]) && (pids[2] == pids[3])));
/* Next, check for the "Too deep!" message: */
warned_too_deep = 0;
/* Use a while loop because multiple processes write to stderr concurrently. */
while (!warned_too_deep && !feof(err)) {
char too_deep[11];
fgets(too_deep, 11, err);
if (!strncmp(too_deep, "Too deep!\n", 10))
warned_too_deep = 1;
}
quit_if(!warned_too_deep);
fclose(out);
fclose(err);
return EXIT_SUCCESS;
}
/*
* Main entry point for SMP1 test harness
*/
int run_smp1_tests(int argc, char **argv)
{
/* Tests can be invoked by matching their name or their suite name
or 'all' */
testentry_t tests[] = {
{ "sub", "smp1", test_sub },
{ "rerun", "smp1", test_rerun },
{ "counter", "smp1", test_counter },
{ "path", "smp1", test_path } };
int result = run_testrunner(argc, argv, tests, sizeof(tests) / sizeof (testentry_t));
unlink("smp1.in");
unlink("smp1.out");
unlink("smp1.err");
return result;
}
I apologize for not having enough time tonight to answer more questions. In about 3 hours, more experts should arrive on the scene.
ASKER
Thats OK no problem....I hope somebody will tell me something...regarding this.....
Well lets wait and see......
If you could post the code that is missing, that may be helpful. Then an expert could actually build the program and witness the failures you are showing. Perhaps you are missing some command line arguments after the -test argument that are necessary for all the different tests.If you step through the program (I use ddd; and sometimes insight), then you can see where the called function returns an error. Then, if you are still not understanding the code, you can point to the area that you need help with. I'll be back late tonight and will try to respond to your full listing tomorrow. But I hope you'll be able to get a quicker response if you list the entire program so that they can build it and see what is wrong.
ASKER
There are like 5 or 6 files including header files..............So shall I post all the files or just the one with .c extensions. I have 3 files with .c extensions... ( shell.c, testrunner.c and smp1_tests.c)....
Thank You...
Can you put into a zip file the entire project: source code (.h and .c) and also the makefile? If there are any input files needed, include them as well, but change extension to .txt (and give instructions on original filenames). Include the folder paths, if possible; otherwise, give instructions as to how the files fan out into a folder tree.
ASKER
OK Phoffric....as you said I have created a zip file with .txt extension of all the files and attached here.......
Please have a look.......
Thank You
program.zip
program.txt
Hi sambho,
I took a quick look at your project, and online as well. I see that this project is academic in nature. If this is an academic project that you are working on, could you please let me know. You are aware of the EE Academic Policy that includes self-study; so that is why I am asking you. Thanks.
The make built OK.
I took a quick look at your project, and online as well. I see that this project is academic in nature. If this is an academic project that you are working on, could you please let me know. You are aware of the EE Academic Policy that includes self-study; so that is why I am asking you. Thanks.
The make built OK.
ASKER
Yes this project is very much academic in nature.......but this is not homework or an assignment problem.
This is just a random project I picked up for learning purpose which I want to learn very much..But I don't know how to play with this project or how to get desired results from it or more specifically what kind of command line arguments should be given to analyze the result and learn the functionalities of the program.....
Your help will be appreciated....Thank You........
This is just a random project I picked up for learning purpose which I want to learn very much..But I don't know how to play with this project or how to get desired results from it or more specifically what kind of command line arguments should be given to analyze the result and learn the functionalities of the program.....
Your help will be appreciated....Thank You........
>> $ ./shell
>> Shell(pid=593)> -test
The -test option is a to be used external to the shell prompt. That is:
$ ./shell -test
If using the shell prompt, then you can issue unix commands; for example:
$ ./shell
Shell(pid=2268)> ls -lrt
imthechild: calling execv with ls, args[0] = ls <--- Note: I added this debug to verify fork OK
Parent says 'wait() returned so the child with pid=1752 is finished.'
Parent says 'Child process 1752 failed with code 255'
Shell(pid=2268)> exit
Exiting process 2268
>> Shell(pid=593)> -test
The -test option is a to be used external to the shell prompt. That is:
$ ./shell -test
If using the shell prompt, then you can issue unix commands; for example:
$ ./shell
Shell(pid=2268)> ls -lrt
imthechild: calling execv with ls, args[0] = ls <--- Note: I added this debug to verify fork OK
Parent says 'wait() returned so the child with pid=1752 is finished.'
Parent says 'Child process 1752 failed with code 255'
Shell(pid=2268)> exit
Exiting process 2268
That failed because the path in the shell didn't have the path set up correctly. So, I'll include the full path:
Shell(pid=868)> /usr/bin/ls -lrt
imthechild: calling execv with /usr/bin/ls, args[0] = /usr/bin/ls
total 153
-rwxrwxrwx 1 ddd None 6386 2007-11-22 15:05 testrunner.c
-rwxrwxrwx 1 ddd None 104 2007-11-22 15:05 b.sh
-rwxrwxrwx 1 ddd None 404 2007-11-22 15:05 Makefile.orig
-rwxrwxrwx 1 ddd None 368 2007-11-22 15:05 testrunner.h
-rwxrwxrwx 1 ddd None 154 2007-11-22 15:05 smp1_tests.h
-rwxrwxrwx 1 ddd None 4019 2007-11-22 15:05 smp1_tests.c
-rwxrwxrwx 1 ddd None 5011 2007-11-26 23:00 shell.c_orig
-rwxrwxrwx 1 ddd None 5176 2007-12-01 15:55 README.txt
-rwxrwxrwx 1 ddd None 9247 2010-10-12 01:32 program.zip
-rwxrwxrwx 1 ddd None 9247 2010-10-12 01:32 program1.zip
-rwxrwxrwx 1 ddd None 410 2010-10-12 15:42 Makefile
-rw-r--r-- 1 ddd None 10423 2010-10-12 15:43 smp1_tests.o
-rw-r--r-- 1 ddd None 12757 2010-10-12 15:43 testrunner.o
-rwxrwxrwx 1 ddd None 5319 2010-10-13 08:07 shell.c
-rw-r--r-- 1 ddd None 5526 2010-10-13 08:07 shell.o
-rwxr-xr-x 1 ddd None 50531 2010-10-13 08:07 shell.exe
Parent says 'wait() returned so the child with pid=3936 is finished.'
Shell(pid=868)> exit
Exiting process 868
Shell(pid=868)> /usr/bin/ls -lrt
imthechild: calling execv with /usr/bin/ls, args[0] = /usr/bin/ls
total 153
-rwxrwxrwx 1 ddd None 6386 2007-11-22 15:05 testrunner.c
-rwxrwxrwx 1 ddd None 104 2007-11-22 15:05 b.sh
-rwxrwxrwx 1 ddd None 404 2007-11-22 15:05 Makefile.orig
-rwxrwxrwx 1 ddd None 368 2007-11-22 15:05 testrunner.h
-rwxrwxrwx 1 ddd None 154 2007-11-22 15:05 smp1_tests.h
-rwxrwxrwx 1 ddd None 4019 2007-11-22 15:05 smp1_tests.c
-rwxrwxrwx 1 ddd None 5011 2007-11-26 23:00 shell.c_orig
-rwxrwxrwx 1 ddd None 5176 2007-12-01 15:55 README.txt
-rwxrwxrwx 1 ddd None 9247 2010-10-12 01:32 program.zip
-rwxrwxrwx 1 ddd None 9247 2010-10-12 01:32 program1.zip
-rwxrwxrwx 1 ddd None 410 2010-10-12 15:42 Makefile
-rw-r--r-- 1 ddd None 10423 2010-10-12 15:43 smp1_tests.o
-rw-r--r-- 1 ddd None 12757 2010-10-12 15:43 testrunner.o
-rwxrwxrwx 1 ddd None 5319 2010-10-13 08:07 shell.c
-rw-r--r-- 1 ddd None 5526 2010-10-13 08:07 shell.o
-rwxr-xr-x 1 ddd None 50531 2010-10-13 08:07 shell.exe
Parent says 'wait() returned so the child with pid=3936 is finished.'
Shell(pid=868)> exit
Exiting process 868
ASKER
Thanks a lot Phofiric,
Now I know how to start studying this program.........Ok so basically I can implement linux commands here, right? The program basically shows how fork() creates child process to run the input command i,e argv[]... IS it true or is it little different than that...
But I have a problem.....When I issue same command it doesn't run.... it says.....
]$ ./shell
Shell(pid=20403)> /usr/bin/ls -lrt
Parent says 'child process has been forked with pid=20407'
Parent says 'wait() returned so the child with pid=20407 is finished.'
Parent says 'Child process 20407 failed with code 255'
I don't know what is the problem.....
Thank You Phoffric.......for your help.......
Now I know how to start studying this program.........Ok so basically I can implement linux commands here, right? The program basically shows how fork() creates child process to run the input command i,e argv[]... IS it true or is it little different than that...
But I have a problem.....When I issue same command it doesn't run.... it says.....
]$ ./shell
Shell(pid=20403)> /usr/bin/ls -lrt
Parent says 'child process has been forked with pid=20407'
Parent says 'wait() returned so the child with pid=20407 is finished.'
Parent says 'Child process 20407 failed with code 255'
I don't know what is the problem.....
Thank You Phoffric.......for your help.......
Maybe my Cygwin is different than your *nix version??
From your regular shell, try "whereis" and "which" to see where you might find your ls command. (Not all *nix versions have both "whereis" and "which".
$ whereis ls
ls: /bin/ls.exe /usr/bin/ls.exe /usr/share/man/man1/ls.1.g z
$ which ls
/usr/bin/ls
For example, this also worked for me:
Shell(pid=1300)> /bin/ls -lrt
From your regular shell, try "whereis" and "which" to see where you might find your ls command. (Not all *nix versions have both "whereis" and "which".
$ whereis ls
ls: /bin/ls.exe /usr/bin/ls.exe /usr/share/man/man1/ls.1.g
$ which ls
/usr/bin/ls
For example, this also worked for me:
Shell(pid=1300)> /bin/ls -lrt
>> so basically I can implement linux commands here, right? The program basically shows how fork() creates child process to run the input command i,e argv[]... IS it true or is it little different than that...
For the one case we talked about, yes, the command and its command line arguments get filled into argv[] and then can be executed by the shell that you defined. Look at the code, and you see special code for "cd" and "exit", for example. You can now make up any user defined commands and add them into this list.
The -test option shows other things that this program can do, but I haven't looked at that in any detail.
For the one case we talked about, yes, the command and its command line arguments get filled into argv[] and then can be executed by the shell that you defined. Look at the code, and you see special code for "cd" and "exit", for example. You can now make up any user defined commands and add them into this list.
The -test option shows other things that this program can do, but I haven't looked at that in any detail.
ASKER
Oh yes I found it in my system............it is
Shell(pid=26266)> /bin/ls -lst
Parent says 'child process has been forked with pid=26269'
total 132
8 -rwxrwxr-x 1 ssapkota ssapkota 5227 Oct 10 18:06 fork02
4 -rw-rw-r-- 1 ssapkota ssapkota 1659 Oct 10 18:05 Fork02.c
8 -rwxrwxr-x 1 ssapkota ssapkota 5124 Oct 10 17:44 fork
And also Mr. Phoffric........I tried cd command but I could not run cd command and I could not find the location of CD command....
i looked in the code but could not find the code for the CD command...if you have time then can you show me that piece of code for cd command...
Thank You very much...............
ASKER
Oh I found.........code for CD also and implemented that one too..
Shell(pid=26598)> cd /bin
Shell(pid=26598)> /bin/ls -lst
Parent says 'child process has been forked with pid=26601'
total 7480
1072 -rwxr-xr-x 1 root root 1089956 Jul 22 2009 ksh
4 lrwxrwxrwx 1 root root 4 May 20 2009 mailx -> mail
4 lrwxrwxrwx 1 root root 2 May 20 2009 ex -> vi
4 lrwxrwxrwx 1 root root 2 May 20 2009 rvi -> vi
4 lrwxrwxrwx 1 root root 2 May 20 2009 rview -> vi
4 lrwxrwxrwx 1 root root 2 May 20 2009 view -> vi
4 lrwxrwxrwx 1 root root 4 May 20 2009 csh -> tcsh
4 lrwxrwxrwx 1 root root 3 May 20 2009 gtar -> tar
4 lrwxrwxrwx 1 root root 8 May 20 2009 dnsdomainn
I will ask you few more questions little later.....
Thank You
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
oh yes I understand................ ..I will end this thread right here......and start same discussion on the new thread......
though , I have one question to ask that you mentioned earlier about -test.....
You said...
>> $ ./shell
>> Shell(pid=593)> -test
The -test option is a to be used external to the shell prompt. That is:
$ ./shell -test
But when I did..........
$ ./shell -test
Test '(empty)' not found
Valid tests : all sub rerun counter path
Valid suites: smp1
I don't understand what it means? i understood it should be used external to the shell prompt but what does it mean by Valid tests : all sub rerun counter path......
Thank You......
though , I have one question to ask that you mentioned earlier about -test.....
You said...
>> $ ./shell
>> Shell(pid=593)> -test
The -test option is a to be used external to the shell prompt. That is:
$ ./shell -test
But when I did..........
$ ./shell -test
Test '(empty)' not found
Valid tests : all sub rerun counter path
Valid suites: smp1
I don't understand what it means? i understood it should be used external to the shell prompt but what does it mean by Valid tests : all sub rerun counter path......
Thank You......
In my first post, I pointed out that when -test option is used, then the run_smp1_tests function is called (otherwise it is not called).
This function has a table:
testentry_t tests[]
which shows the test entry points for a suite of tests. We would have to look at each entry point and the run_testrunner function which exercises each test to fully understand what is going on. Some of your results requires a little searching, sometimes with not obvious results:
For example:
$ grep "counter" *
README.txt: 2. Modify this MP so that the command prompt includes a counter that
README.txt: "Shell(pid=%1)%2> " %1=process pid %2=counter
README.txt: Do not increment the counter if no command is supplied to execute.
README.txt: Test: ./shell -test counter
Binary file shell.exe matches
smp1_tests.c:/* P5.2: Test of command line counter */
smp1_tests.c:int test_counter(int argc, char **argv)
smp1_tests.c: { "counter", "smp1", test_counter },
Binary file smp1_tests.o matches
I suggest adding printf trace and debug statements so that you know you are in this test suite, and print out some useful values. It will take a bit of work and detailed examination of all the source code you provided. But just do one test at a time, and see what the purpose of each one is.
This function has a table:
testentry_t tests[]
which shows the test entry points for a suite of tests. We would have to look at each entry point and the run_testrunner function which exercises each test to fully understand what is going on. Some of your results requires a little searching, sometimes with not obvious results:
For example:
$ grep "counter" *
README.txt: 2. Modify this MP so that the command prompt includes a counter that
README.txt: "Shell(pid=%1)%2> " %1=process pid %2=counter
README.txt: Do not increment the counter if no command is supplied to execute.
README.txt: Test: ./shell -test counter
Binary file shell.exe matches
smp1_tests.c:/* P5.2: Test of command line counter */
smp1_tests.c:int test_counter(int argc, char **argv)
smp1_tests.c: { "counter", "smp1", test_counter },
Binary file smp1_tests.o matches
I suggest adding printf trace and debug statements so that you know you are in this test suite, and print out some useful values. It will take a bit of work and detailed examination of all the source code you provided. But just do one test at a time, and see what the purpose of each one is.
ASKER
thank You very much Phoffric for your time and explanations............
You are very welcome. Hope it helped.
i keep trying to track the code that actually performs the four tests in the make test but i feel like its just passing arguements to various functions that never end up really doing anything... help!
You did ask one specific question which I will try to help you with:
>> I don't know what kind of command line input should be given after running this program....
Below is your code (LOCs 62-65):
If there are no arguments in the command line, then argc is 1, and argc > 1 is false, so the next line
return run_smp1_tests(argc - 1, argv + 1);
will *not* be executed.
If there are one or more arguments with the first one being "-test" as in:
$ ./a.exe -test more-arguments-as-needed
then the run_smp1_tests() function is called with one less argument (for the first parameter), and the argv pointer incremented by 1, thereby skipping the first string value (i.e., in my example, that would be "./a.exe").
I cannot say what run_smp1_tests() does since it is probably defined in your smp1_tests.h include file, which is not posted.
It appears that if the arguments are described as above, then run_smp1_tests() is called, and after completing, it returns a status, which is passed upwards to the shell that invoked the program. The rest of the program in main() is not executed since the program has a return.
If the arguments are not as described above, then run_smp1_tests() is not called, and the rest of the program is executed.
I hope this helps a little. I realize that there are potentially another 140 questions, and I have only addressed one.
Open in new window