0
votes

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);
}
2
typical char c. Added to codeXyzk
It needs to be an int.teppic
Why are you checking if (c == 4)? You should be checking for EOF only. Character #4 is not special. (It is typically the EOF character for cooked mode terminal processing, but that's only relevant to the tty driver.)Celada
What is the code for childFunction()?FatalError
4 is End of Transmission. I use it to debug program from console input, instead of using files.Xyzk

2 Answers

1
votes

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).

0
votes

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.