Get value from execl() call - c

I have made this program to run n other c programs. Suppose I want to execute three c programs :
1. Half of a Number
2. Double of a Number
3. Square of a Number
I am taking these three file names as the arguments from the command line and a Digit
Suppose I give the arguments : half square double 10
then the program execution will be double(square(half(10)))
So the output should be 50
I have made these three programs in such a way that these accept the number from the command line.
Now I am clueless that How can I return the value from that c programs which I have calculated . I have tried exit() and WEXITSTATUS(status) function but not getting the correct output
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
#include<wait.h>
char* concat(char *s1, char *s2)
{
char *result =(char *) malloc(strlen(s1)+strlen(s2)+1);
strcpy(result, s1);
strcat(result, s2);
return result;
}
int main(int arg, char** args)
{
int status,cpid;
int n=arg;
char* val = (args[n-1]);
char* path="/home/naman/"; //This is the path where I have my all C programs
if(arg<3)
printf("Too less arguments\n");
printf("Main program pid is : %d",(int)getpid());
printf("\n");
for(int i=1;i<n-1;i++)
{
if(fork())
{
wait(NULL);
printf("Value return is : %d\n",WEXITSTATUS(status)); \\Not getting to correct value from that executed program
}
else
{
char* result=concat(path,args[i]);
//printf("%s \n",result);
execl(result,args[i],val,(char*)0);
printf("I will never come here");
}
}
printf("Value is : %d",atoi(val));
}

Related

using if statements with command line parameters in c

I am having trouble with getting my if statements to work with parameters from the command line. I get an error saying, 'comparison between pointer and integer ('char *' and 'int')' every time. Any help will be greatly appreciated. Here is the description for what I have to do:
This program will read a parameter from the command line and translate it to the name of the corresponding month. I.e. if you run the program with the following parameter:
It will print the following message:
The month is 'April'.
#include <stdio.h>
int main(int argc, char *argv[]) {
if(argv[1] == 1){
printf("You entered the number 1.");
} else {
printf("You entered a different number.");
}
return 0;
}
The parameters passed on the command line are strings, so you need to use strcmp to compare them.
int main(int argc, char *argv[]) {
if(argc > 1 && (strcmp(argv[1],"1") == 0)){
printf("You entered the number 1.");
} else {
printf("You entered a different number.");
}
return 0;
}
Compiler is right - you are comparing char * and int.
You have to either convert argv[1] to int (e.g. with strol()) or convert 1 to char * (by adding quotes - "1") and then compare with strcmp() instead of ==.
And checking number of arguments in argc is also something you should do, when working with arguments. (thanks #Ingo Leonhardt)
Argv returns pointer to array of chars, so your programm must looks like:
#include <stdio.h>
int main(int argc, char *argv[]) {
if(argv[1][0] == '1'){
printf("You entered the number 1.");
} else {
printf("You entered a different number.");
}
return 0;
}
Or you can use atoi (man 2 atoi) function to convert ascii array to int like this:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
if(atoi(argv[1]) == 1){
printf("You entered the number 1.");
} else {
printf("You entered a different number.");
}
return 0;
}
If you want to use your command line parameter like a integer, you must modify the type with atoi
#include <stdio.h>
int main(int argc, char *argv[]) {
if(atoi(argv[1]) == 1){
printf("You entered the number 1.");
} else {
printf("You entered a different number.");
}
return 0;
}

simple shell in c: waitpid system call not working

I have to make simple shell which read commands and execute them in order. condition is not changing the form of main function, and execute function should be recursive.
main problem is that it seems waitpid doesn't work. but I know, there are so many problem in my code. please let me know where I should start from..
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#define MAX 10
char cmmd[MAX][256];
int sp;
char *argv[10];
int size;
void ClearLineFromReadBuffer(void){
while(getchar() != '\n');
}
void printCommands(){
size = sp+1;
//print by moving stack pointer
while(1){
if (sp==-1) break;
printf("Command line : %s\n", cmmd[sp]);
sp--;
}
printf("print end\n");
}
void readCommandLines(){
int a = 0; //return of scanf
while (1){ //write commends to cmmd untill get ctrl+d
printf(">");
a = (scanf("%[^\n]s", cmmd[sp])); //take input to str untill get enter(scanf returns -1)
if (a==-1) {sp--; break;}
if (a==1) ClearLineFromReadBuffer();
if (a==0) {printf("error"); break;}
sp++;
}
printf("\n");
}
void readACommand(char *line){ //line takes string's name.
int i=0;
argv[i]=strtok(line," "); //i==0
while(strtok(line," ")!=NULL){
i++;
argv[i]=strtok(NULL," ");
}
printf("%s",argv[0]);
printf("%s",argv[1]);
}
void executeCommands(){ //Recursive function
int n = sp;
n++;
printf("%d",n);
printf("%s",cmmd[n]);
char *cmd_line = cmmd[n]; //command line which child process will execute
unsigned int child_pid; //fork() returns process id of child in parents process
int status; //status takes return of child's exit()
child_pid=fork();
if (child_pid != 0){ // Parents process
printf("parents access");
waitpid(child_pid,&status,0);
printf("***Process %d Child process %d DONE with status %x\n\n",getpid(),child_pid,status);
sp++;
if(sp<size)
executeCommands();
}
else if (child_pid == 0){ //fork() returns 0 in child process
printf("***Process %d Executing Command %s",getpid(),cmd_line);
readACommand(cmmd[n]);
execve(argv[0],argv,NULL);
printf("ERROR - not executing command \"%s\"\n",argv[0]); //can be printed because exec() failed
}
}
int main(){
readCommandLines();
printCommands();
executeCommands();
return(0);
}
this is outcome.
enter image description here
the way you're tokenizing the string is very wrong. There's a lot of strtok calls, and your loop can be an infinite loop since you're calling strtok in the loop with the initialization string, not NULL
Plus you're not setting to NULL after the last argument, which is required by execv to know when the arguments have run out (no size is passed)
Here's a standalone example and a proper readACommand routine:
#include <stdio.h>
#include <string.h>
char *argv[100];
void readACommand(char *line){ //line takes string's name.
int i=0;
argv[i]=strtok(line," "); //i==0
while(argv[i]!=NULL){
argv[++i]=strtok(NULL," ");
}
}
int main()
{
char line[] = "this is a command";
char **ptr=argv;
readACommand(line);
while(*ptr != NULL)
{
printf("Arg: %s\n",*ptr);
ptr++;
}
return 0;
}
executing (detecting the NULL pointer in the end):
Arg: this
Arg: is
Arg: a
Arg: command

C getting input from CMD

How do you get input using prompt? I tried compiling the code bellow into "a.exe" and executing it from CMD like "gcc a.exe 5", but it doesn't output the number like it was supposed to.
#include <stdio.h>
int main(int a)
{
printf("%d\n", a);
return 1;
}
Have I done anything wrong when installing the compiler or am I trying to run it wrong?
Your main() parameters are wrong, you should do it this way:
int main(int argc, char **argv) {
if(argc > 2) {
printf("%s\n", argv[2]);
}
else {
printf("No arguments\n");
}
}
Note that int argc represents the number of parameters and char **argv is an array containing all the parameters, as strings, including "gcc", "a.exe", etc.
In your case, if you run your program this way: gcc a.exe 5, your parameters would be: argc = 3, argv = ["gcc", "a.exe", "5"]
To get input using the prompt, the easiest way would simply be to use a scanf statement. scanf basically waits for, and scans user input, which can then be stored as a variable. For example, a code that would take input for "Give me a number." and then spits back the result would be:
#include <stdio.h>
int main()
{
int num; //Initializes variable
printf("Please give me a number.\n"); //Asks for input
scanf("%d", &num); //scanf is the function, %d reserves the space, and the &*variable* sets the input equal to the variable.
getchar(); //Waits for user to input.
printf("Your number was %d.\n", num); //Spits it back out.
return 0;
}
The output would be:
[PROGRAM BEGINS]
Please give me a number.
>>>5
Your number was 5.
[PROGRAM ENDS]
#include <stdio.h>
int main(int argc, char *argv[])
{
if(argc == 2)
printf("%d\n", atoi(argv[1]));
return 0;
}

sprintf() command doesnt work

I am trying to write an c program which get two float numbers from user and then calls another program with execv() command. But I can't do it , because of converting float to char or I don't know why.
The problem is execv() command is not working; the output must be like that
Enter first num: 5 Enter second num: 7
5.000000 + 7.000000 = 12.000000 parentPID: 9745 childPID: 9746 works now
but it is is like that now
Enter first num: 5 Enter second num: 7 parentPID: 9753
childPID: 9754 works now
my first c program sum.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char **argv) {
if(argc!=3)
printf("error...\n");
double a=atof(argv[1]);
double b=atof(argv[2]);
printf("%lf + %lf = %lf \n",a,b,a+b);
return 0;
}
and the second program calculate.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
float x,y;
pid_t pid;
printf("Enter first num: ");
scanf("%f",&x);
printf("Enter second num: ");
scanf("%f",&y);
if((pid=fork())== -1)
{
printf("can not fork..\n");
exit(1);
}
if(pid==0) //child
{
pid=getpid();
char *temp[] = {NULL,NULL,NULL,NULL};
temp[0]="sum";
sprintf(*temp[1],"%f",x); //here I want to convert float number to char but it doesn't work
sprintf(*temp[2],"%f",y);
execv("sum",temp);
}
else
{
wait(NULL);
printf("parentPID: %d childPID: %d works now.\n", getpid(), pid);
}
return 0;
}
char command1[50], command2[50]; // Added
char *temp[] = {NULL, command1, command2, NULL}; // Modified
temp[0]="sum";
sprintf(temp[1],"%f",x); // remove *
sprintf(temp[2],"%f",y); // remove *
You are not allocating to temp[1] and temp[2] and using those as destination buffer in sprintf and using incorrect * in sprint.
You can use malloc to allocate this memory or use other string as shown in above example to initialize the array.
From kind comment of Sourav Ghosh:
In sum.c, change below lines of code to:
if(argc!=3)
{
printf("error...\n");
return -1;
}
or else, it may lead to undefined behaviour.

C: Unable to exit program with multiple inputs

This code is supposed to exit when I type in EXIT, but when I type EXIT nothing happens, anything I input after it exits the program. Can someone point out what's wrong? Although it works fine when I don't scan multiple inputs.
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main(){
char cmd[50];
char cmd1[10];
char cmd2[10];
char str;
int x, y, sum;
while(1){
scanf("%s%d%c%d", &cmd ,&x, &str, &y);
if(strstr(cmd,"SUM")){
sum = x + y;
scanf("%s %s",&cmd1, &cmd2);
if((strstr(cmd1,"DSP")) && (strstr(cmd2,"X")))
{
printf("%d\n",sum);
}
else
{
printf(" ");
}
}
else if(strstr(cmd,"EXIT"))
{
break;
}
else
{
printf("INVALID INPUT!\n");
}
}
return 0;
}
It's because of how you use scanf, it will wait for all formats to be read (or it fails).
Instead I suggest you get input using e.g. fgets, then check for command, and if it's e,g. "SUM" then you parse the command arguments.

Resources