0

I'm trying to execute printf(">>"); only once in the parent process. Meaning that once I call fork() and a child process is born, the program (once it starts executing code from the top again), should skip printf(">>");

Note: I'm trying to implement something very similar to the Python Shell. Notice how when you enter print("example") in the Python Shell, it print "example" and not ">>>example"

I apologize for the low readability, I really tried my best.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>

int main(){

char * selected = malloc(256);
char line[255];
pid_t pid = getpid();

while (1){

    printf("(In parent) PID: %d, PPID: %d\n", getpid(), getppid());

    // if (ps is parent && line is NOT executed later on by fork){
    printf(">>");
    //}

    fgets(line, sizeof(line), stdin);
    line[strlen(line) - 1] = '\0'; // removes \n 

    if (strcmp(line, "fork") == 0){
        pid = fork();
        if (pid == 0){
            printf("(In child) PID: %d, PPID: %d\n", getpid(), getppid());
        }
    }
}

return 0;
}
bruno
  • 32,421
  • 7
  • 25
  • 37
HamzaKerem
  • 121
  • 1
  • 8
  • 1
    `if (pid != 0)` ? `fork()` returns `0` if you are in the child, so... use that information. – KamilCuk Jul 14 '20 at 12:49
  • if you want to only do `printf("(In child) PID: %d, PPID: %d\n", getpid(), getppid());` in the child just do `exit(0);` or `return 0;` after, and `wait(NULL);` in else branch – bruno Jul 14 '20 at 12:50
  • 1
    anyway your question is unclear, do you want to also loop and `fgets` in child ? do you want child has child too etc ? – bruno Jul 14 '20 at 12:54
  • @KamilCuk doesn't work for when used before pid = fork() – HamzaKerem Jul 14 '20 at 12:55
  • @bruno no need for multiple child ps's – HamzaKerem Jul 14 '20 at 12:56
  • @mumcuhkm34 so what the alone child has to do except `printf("(In child) PID: %d, PPID: %d\n", getpid(), getppid());` ? – bruno Jul 14 '20 at 12:56
  • @bruno nothing for now, will implement execlp() once i get this to work. But for now just want to have it print PID & PPID without the programming printing ">>" right before it. – HamzaKerem Jul 14 '20 at 13:01
  • @mumcuhkm34 to say what you do not want does not help to know what you want. What the child process must do ? also why the `while` if "*I'm trying to execute printf(">>"); **only once** in the parent process*" ? – bruno Jul 14 '20 at 13:02
  • @bruno just trying to give an idea of what I want to achieve. The only once part means don't execute that line after fork is called. – HamzaKerem Jul 14 '20 at 13:03
  • sorry but "an idea of" is not a specification, please edit your question when you will know, currently it is not possible to help you – bruno Jul 14 '20 at 13:05
  • 1
    `line[strlen(line) - 1] = '\0'; // removes \n` *No*, it doesn't "remove \n". It removes the last character read, which doesn't have to be `'\n'`. If `fgets()` returns a zero-length string, you invoke undefined behavior because `strlen(line)` is zero and `strlen(line) - 1` falls outside the bounds of the array. And if `fgets()` fails the contents of `line` could be indeterminate, which means you've just invoked undefined behavior. Return values for I/O calls such as `fgets()` must be checked for failure. If `fgets()` works, `line[ strcspn( line, "\n" ) ] = 0;` will properly remove the `'\n'`. – Andrew Henle Jul 14 '20 at 13:19
  • @mumcuhkm34 : Why are you tagging this _shell_? Your question does not involve a shell. – user1934428 Jul 14 '20 at 14:00
  • 1
    Does this answer your question? [printf anomaly after "fork()"](https://stackoverflow.com/questions/2530663/printf-anomaly-after-fork) – Joseph Sible-Reinstate Monica Jul 14 '20 at 21:42
  • @JosephSible-ReinstateMonica well found. Unfortunately I cannot vote your duplicate after I retracted an other close reason until the question is edited – bruno Jul 15 '20 at 07:31

1 Answers1

1

Just call printf(">>"); followed by fflush(NULL); (read fflush(3)) before your fork().

Remember that stdio(3) is buffered. See setvbuf(3) and use strace(1) and gdb(1).

Read also Advanced Linux Programming and syscalls(2)

Consider also studying, for inspiration, the source code of small shells such as sash.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547