Why does fprintf start printing out of order or not at all?
- by Steve Melvin
This code should take an integer, create pipes, spawn two children, wait until they are dead, and start all over again. However, around the third time around the loop I lose my prompt to enter a number and it no longer prints the number I've entered. Any ideas?
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#define WRITE 1
#define READ 0
int main (int argc, const char * argv[]) {
//Pipe file-descriptor array
unsigned int isChildA = 0;
int pipeA[2];
int pipeB[2];
int num = 0;
while(1){
fprintf(stderr,"Enter an integer: ");
scanf("%i", &num);
if(num == 0){
fprintf(stderr,"You entered zero, exiting...\n");
exit(0);
}
//Open Pipes
if(pipe(pipeA) < 0){
fprintf(stderr,"Could not create pipe A.\n");
exit(1);
}
if(pipe(pipeB) < 0){
fprintf(stderr,"Could not create pipe B.\n");
exit(1);
}
fprintf(stderr,"Value read: %i \n", num);
fprintf(stderr,"Parent PID: %i\n", getpid());
pid_t procID = fork();
switch (procID) {
case -1:
fprintf(stderr,"Fork error, quitting...\n");
exit(1);
break;
case 0:
isChildA = 1;
break;
default:
procID = fork();
if (procID<0) {
fprintf(stderr,"Fork error, quitting...\n");
exit(1);
}
else if(procID == 0){
isChildA = 0;
}
else {
write(pipeA[WRITE], &num, sizeof(int));
close(pipeA[WRITE]);
close(pipeA[READ]);
close(pipeB[WRITE]);
close(pipeB[READ]);
pid_t pid;
while (pid = waitpid(-1, NULL, 0)) {
if (errno == ECHILD) {
break;
}
}
}
break;
}
if (procID == 0) {
//We're a child, do kid-stuff.
ssize_t bytesRead = 0;
int response;
while (1) {
while (bytesRead == 0) {
bytesRead = read((isChildA?pipeA[READ]:pipeB[READ]), &response, sizeof(int));
}
if (response < 2) {
//Kill other child and self
fprintf(stderr, "Terminating PROCID: %i\n", getpid());
write((isChildA?pipeB[WRITE]:pipeA[WRITE]), &response, sizeof(int));
close(pipeA[WRITE]);
close(pipeA[READ]);
close(pipeB[WRITE]);
close(pipeB[READ]);
return 0;
}
else if(!(response%2)){
//Even
response/=2;
fprintf(stderr,"PROCID: %i, VALUE: %i\n", getpid(), response);
write((isChildA?pipeB[WRITE]:pipeA[WRITE]), &response, sizeof(int));
bytesRead = 0;
}
else {
//Odd
response*=3;
response++;
fprintf(stderr,"PROCID: %i, VALUE: %i\n", getpid(), response);
write((isChildA?pipeB[WRITE]:pipeA[WRITE]), &response, sizeof(int));
bytesRead = 0;
}
}
}
}
return 0;
}
This is the output I am getting...
bash-3.00$ ./proj2
Enter an integer: 101
Value read: 101
Parent PID: 9379
PROCID: 9380, VALUE: 304
PROCID: 9381, VALUE: 152
PROCID: 9380, VALUE: 76
PROCID: 9381, VALUE: 38
PROCID: 9380, VALUE: 19
PROCID: 9381, VALUE: 58
PROCID: 9380, VALUE: 29
PROCID: 9381, VALUE: 88
PROCID: 9380, VALUE: 44
PROCID: 9381, VALUE: 22
PROCID: 9380, VALUE: 11
PROCID: 9381, VALUE: 34
PROCID: 9380, VALUE: 17
PROCID: 9381, VALUE: 52
PROCID: 9380, VALUE: 26
PROCID: 9381, VALUE: 13
PROCID: 9380, VALUE: 40
PROCID: 9381, VALUE: 20
PROCID: 9380, VALUE: 10
PROCID: 9381, VALUE: 5
PROCID: 9380, VALUE: 16
PROCID: 9381, VALUE: 8
PROCID: 9380, VALUE: 4
PROCID: 9381, VALUE: 2
PROCID: 9380, VALUE: 1
Terminating PROCID: 9381
Terminating PROCID: 9380
Enter an integer: 102
Value read: 102
Parent PID: 9379
PROCID: 9386, VALUE: 51
PROCID: 9387, VALUE: 154
PROCID: 9386, VALUE: 77
PROCID: 9387, VALUE: 232
PROCID: 9386, VALUE: 116
PROCID: 9387, VALUE: 58
PROCID: 9386, VALUE: 29
PROCID: 9387, VALUE: 88
PROCID: 9386, VALUE: 44
PROCID: 9387, VALUE: 22
PROCID: 9386, VALUE: 11
PROCID: 9387, VALUE: 34
PROCID: 9386, VALUE: 17
PROCID: 9387, VALUE: 52
PROCID: 9386, VALUE: 26
PROCID: 9387, VALUE: 13
PROCID: 9386, VALUE: 40
PROCID: 9387, VALUE: 20
PROCID: 9386, VALUE: 10
PROCID: 9387, VALUE: 5
PROCID: 9386, VALUE: 16
PROCID: 9387, VALUE: 8
PROCID: 9386, VALUE: 4
PROCID: 9387, VALUE: 2
PROCID: 9386, VALUE: 1
Terminating PROCID: 9387
Terminating PROCID: 9386
Enter an integer: 104
Value read: 104
Parent PID: 9379
Enter an integer: PROCID: 9388, VALUE: 52
PROCID: 9389, VALUE: 26
PROCID: 9388, VALUE: 13
PROCID: 9389, VALUE: 40
PROCID: 9388, VALUE: 20
PROCID: 9389, VALUE: 10
PROCID: 9388, VALUE: 5
PROCID: 9389, VALUE: 16
PROCID: 9388, VALUE: 8
PROCID: 9389, VALUE: 4
PROCID: 9388, VALUE: 2
PROCID: 9389, VALUE: 1
Terminating PROCID: 9388
Terminating PROCID: 9389
105
Value read: 105
Parent PID: 9379
Enter an integer: PROCID: 9395, VALUE: 316
PROCID: 9396, VALUE: 158
PROCID: 9395, VALUE: 79
PROCID: 9396, VALUE: 238
PROCID: 9395, VALUE: 119
PROCID: 9396, VALUE: 358
PROCID: 9395, VALUE: 179
PROCID: 9396, VALUE: 538
PROCID: 9395, VALUE: 269
PROCID: 9396, VALUE: 808
PROCID: 9395, VALUE: 404
PROCID: 9396, VALUE: 202
PROCID: 9395, VALUE: 101
PROCID: 9396, VALUE: 304
PROCID: 9395, VALUE: 152
PROCID: 9396, VALUE: 76
PROCID: 9395, VALUE: 38
PROCID: 9396, VALUE: 19
PROCID: 9395, VALUE: 58
PROCID: 9396, VALUE: 29
PROCID: 9395, VALUE: 88
PROCID: 9396, VALUE: 44
PROCID: 9395, VALUE: 22
PROCID: 9396, VALUE: 11
PROCID: 9395, VALUE: 34
PROCID: 9396, VALUE: 17
PROCID: 9395, VALUE: 52
PROCID: 9396, VALUE: 26
PROCID: 9395, VALUE: 13
PROCID: 9396, VALUE: 40
PROCID: 9395, VALUE: 20
PROCID: 9396, VALUE: 10
PROCID: 9395, VALUE: 5
PROCID: 9396, VALUE: 16
PROCID: 9395, VALUE: 8
PROCID: 9396, VALUE: 4
PROCID: 9395, VALUE: 2
PROCID: 9396, VALUE: 1
Terminating PROCID: 9395
Terminating PROCID: 9396
105
Value read: 105
Parent PID: 9379
Enter an integer: PROCID: 9397, VALUE: 316
PROCID: 9398, VALUE: 158
PROCID: 9397, VALUE: 79
PROCID: 9398, VALUE: 238
PROCID: 9397, VALUE: 119
PROCID: 9398, VALUE: 358
PROCID: 9397, VALUE: 179
PROCID: 9398, VALUE: 538
PROCID: 9397, VALUE: 269
PROCID: 9398, VALUE: 808
PROCID: 9397, VALUE: 404
PROCID: 9398, VALUE: 202
PROCID: 9397, VALUE: 101
PROCID: 9398, VALUE: 304
PROCID: 9397, VALUE: 152
PROCID: 9398, VALUE: 76
PROCID: 9397, VALUE: 38
PROCID: 9398, VALUE: 19
PROCID: 9397, VALUE: 58
PROCID: 9398, VALUE: 29
PROCID: 9397, VALUE: 88
PROCID: 9398, VALUE: 44
PROCID: 9397, VALUE: 22
PROCID: 9398, VALUE: 11
PROCID: 9397, VALUE: 34
PROCID: 9398, VALUE: 17
PROCID: 9397, VALUE: 52
PROCID: 9398, VALUE: 26
PROCID: 9397, VALUE: 13
PROCID: 9398, VALUE: 40
PROCID: 9397, VALUE: 20
PROCID: 9398, VALUE: 10
PROCID: 9397, VALUE: 5
PROCID: 9398, VALUE: 16
PROCID: 9397, VALUE: 8
PROCID: 9398, VALUE: 4
PROCID: 9397, VALUE: 2
PROCID: 9398, VALUE: 1
Terminating PROCID: 9397
Terminating PROCID: 9398
106
Value read: 106
Parent PID: 9379
Enter an integer: PROCID: 9399, VALUE: 53
PROCID: 9400, VALUE: 160
PROCID: 9399, VALUE: 80
PROCID: 9400, VALUE: 40
PROCID: 9399, VALUE: 20
PROCID: 9400, VALUE: 10
PROCID: 9399, VALUE: 5
PROCID: 9400, VALUE: 16
PROCID: 9399, VALUE: 8
PROCID: 9400, VALUE: 4
PROCID: 9399, VALUE: 2
PROCID: 9400, VALUE: 1
Terminating PROCID: 9399
Terminating PROCID: 9400
^C
Another thing that's strange, when ran from within XCode it behaves normally. However, when ran from bash on Solaris or OSX it acts up.