Xyzk
Xyzk

Reputation: 1342

Program continues to read from redirected stdin after EOF

My program is supposed to read unix command from file, execute it, save result to file. If I simply try to run it from console, there is no problem with execution. If I redirect input to file, however, it for some reason continues to read forever. I think I might not be detecting EOF properly, but this approach seemed to work before.

I tried debugging and results are really strange. or example for a file with input

echo blablabla
true
false

it's input lines will be, in order

echo blablabla
true
falseecho blablabla

As if it read the stdout? Or stdin? But it works if I simply provide input from console.

FILE* script;
script=freopen(argv[argc-1], "r", stdin);
if(script==0){
  printf( "Error 1\n" );
  return 1;
}
int c;

while((c=fgetc(stdin))){
    if(c==EOF || c==4 || c<0){
        c='\n';
        exitLoop=true;
    }
    if(c!='\n'){
        inLine[i]=c;
        inLine[i+1]=0; //shouldn't be needed, but just in case
        i++;
    }else{
        inLine[i]=0;
        printf("inLine: %s i:%d\n\n",inLine,i);
        sleep(1);
        int result= 0;
        result= fork();
        if(result<0){
           printf("Failed creation of a new process. Most likely not enough memory\n");
           return 1;
        }else if(result==0){
           short int ak=childFunction(inLine,logPath,searchPath);
           return ak;
        }else if(result>0){
           int status=0;
           int d=(int)waitpid(result,&status,0);
        }else
           return -1;
        }
        i=0;
        if(exitLoop==true)
        break;
    }
}

edit:

int childFunction(char in[],char logPath[], char searchPath[]){
FILE *logFile= fopen( logPath, "a" );
if(logFile==NULL)
return 1;
char** argv;
int stringCount=1;
char* path;
int i=0,j=0;
for(i=0;in[i]!=0;i++){
    if(in[i]==' ' || in[i]=='\t'){
        in[i]=0;
        stringCount++;
    }
}
argv = malloc(sizeof(char*)*(stringCount+1));
i=0;
argv[0]=in;
j++;
while(j<stringCount){
    if(in[i]==0){
        argv[j]=in+i+1;
        j++;
    }
    i++;
}
argv[stringCount]=NULL;
int processId=fork();
if(processId<0){
    printf("Error while forking.\n");
    exit(1);
}else if(processId==0){
    return execv(in,argv);
}
int c=0;
waitpid(processId,&c,0);
c=errno;
fprintf(logFile,"%d: %s\n", c, in);
fclose(logFile);
free(argv);
if(c!=0)
return(1);
else
return(0);
}

Upvotes: 0

Views: 991

Answers (2)

Xyzk
Xyzk

Reputation: 1342

Okay. No idea what caused the problem. I did manage to go around it however, by reading the length of file beforehand, and simply exiting the loop after x characters were read.

Upvotes: 0

FatalError
FatalError

Reputation: 54641

Your issue is that fgetc() returns an int, not char. Since you want to be able to read any char (i.e. any byte) fgetc() will return the unsigned char value that was entered. EOF is defined as being less than 0, so that it can be distinguished.

You need to define c as an int so that you can identify the EOF, otherwise it will overlap with some valid character's value and as you discovered may not be detectable at all (if char is unsigned).

Upvotes: 2

Related Questions