Search code examples
cfor-loopmkfifo

Loop fails to continue looping


I was working on some code to create a new folder everytime a specific FIFO is written to:

int main (int argc, char* argv[]) {
if (argc != 2) {
    printf("Usage: %s <directory>\n",argv[0]);
    exit(0);
}
int ret = chdir(argv[1]);
if (ret < 0) {
    printf("Could not chdir to %s\n",argv[1]);
    perror("");
    exit(0);
}

ret = mkfifo("create",0666);
if (ret < 0) {
    perror("Could not make create fifo");
    return 0;
}
int ctfd = open("create",O_RDWR);
if (ctfd < 0) {
    perror("Could not open create");
    return 0;
}
char create[1];
//socket counter
int count = 0;
char crdir[15];

for(;;ret = read(ctfd,create,1)) {
    //printf("%s %d\n",create,count);
    if (ret < 0) {
        perror("Failed to read from create");
        continue;
    }
    else if (ret < 1 || create[0] == '\n') {
        continue;
    }

    sprintf(crdir,"%d",count);
    ret = mkdir(crdir,0777);
    if (ret < 0) {
        printf("Failed to create dir");
        perror("");
        continue;
    }
    count++;
    switch(fork()) {
        case -1:
            perror("Failed to fork");
            break;
        case 0:
            printf("%d\n",count);
            break;
        default:
            //char* argv[ ] = {"netclient",cte};
            exit(0);
    }
    printf("test");
}
//execvp()
return 0;

}

However when run this happens:

arthur@dent:~/coding/netdir$ mkdir test
arthur@dent:~/coding/netdir$ ./netserver test &
[1] 2122
arthur@dent:~/coding/netdir$ echo 1 > test/create 
[1]+  Done                    ./netserver test
1

What did I do wrong? Why does it not continue looping and wait for more input? The FIFO is opened for reading and writing so that it would not be closed when the writing stopped, did that not work properly?


Solution

  • Taking a second look, I would say your problem is in switch( fork() ). fork() returns 0 for the child process and the child's PID for the parent but you have exit(0); in default: so you exit the parent.

    Another problem (seen first): Your loop is:

    for(;;ret = read(ctfd,create,1)) {
       do_something;
    }
    

    which is equal to:

    while( 1 ) {
        do_something;
        ret = read(ctfd,create,1);
    }
    

    do you 'do something' before reading. That leads to Undefined Beahaviour, e.g. becaus the contents of create isn't defined.