Search code examples
cprocessfork

C program infinite unary operation not working


I have three c programs double.c to double the integer, root.c to take square root of integer and square to take square of a integer

./root 9
output:3
./square 9
81
./double 3
ouput:6

I want to chain these operation like pattern will be of left to right

./square root square double 8
pattern = double(square(root(square(8))))

or it can be somthing like

./root square 8
pattern = square(root(8))

What i tried is

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <math.h>

double operate(char * operation, double operand) {
    if (strcmp(operation, "square") == 0) {
        return pow(operand, 2);
    } else if (strcmp(operation, "root") == 0) {
        return sqrt(operand);
    } else if (strcmp(operation, "double") == 0) {
        return 2 * operand;
    }
    return 0;
}

int main(int argc, char *argv[]) {
    if (argc < 3) {
        printf("Usage: %s <operand> <operation1> <operation2> ...\n", argv[0]);
        return 1;
    }
    double operand = atof(argv[1]);
    for (int i = 2; i < argc; i++) {
        operand = operate(argv[i], operand);
    }
    printf("Result: %.2f\n", operand);
    return 0;
}

Which work something like

gcc main.c -o main
./main 8 square root double
output = Works fine

But it is somehow different way to do it and there were some constraints before to implement this before Following were constraints

• If your implementation results in parent-child relationship between processes, then parent process must wait for its child process to exit

System calls and library functions You must only use the below mentioned APIs to implement this question

- fork
 - exec* family
 - str* family
 - ato* family
 - printf, sprintf
 - round

But i am unable to grasp this how it is related to process and how it will be done Please guide me some right direction so i can do complete this.


Solution

  • I want to chain these operation like pattern will be of left to right

    ./square root square double 8
    pattern = double(square(root(square(8))))
    

    Presumably, such a chain can start with any of the three operations, so each of your programs needs to know how to do such chaining. Also, as you seem to recognize, the code you present doesn't meet the requirements because it uses a separate command to run the chain.

    Let's consider the constraints for a moment. The requirement (both practical and explicit) that parent processes must wait for their children, combined with omission from the allowed list of any function that would allow parent processes to do so, implies that fork() is a red herring. You must not fork() because you are not permitted to wait.

    Also, neither pow() nor sqrt() is on your list of allowed functions. x * x is a better method of squaring than pow() anyway, but if you want to avoid sqrt() then you'll need to implement a numerical method to compute square roots. For example, you might perform a binary search for the root, or apply Newton's method.

    As for the chaining, I see two main implementation approaches available:

    1. All the programs are the same program, which identifies the first operation in the sequence based on the name by which it is launched (argv[0]). It reads the numeric argument, then just applies each operation in turn, starting at argument 0. It prints the result when there are no more operations to perform.

    OR

    1. The three programs are each specific to a single operation. When run, they pick the numeric operand from their last argument and perform their particular operation on it. Then,

      • if there are no other arguments (argc == 2), they print the result;
      • otherwise, they format the result as a string, and use, say, execve() (without forking) to run the tail of the chain of operations on the intermediate result.

    Details are left as the exercise they are meant to be.