/** Programmed By : m1o2 */ #include #include #include #include #include #include #define WaitForEnter { fprintf(stderr,"\n\n Press the 'Enter' key to continue..."); fflush(stdout); fflush(stdin); getchar(); putchar('\n'); } #define SystemError( msg ) { fprintf(stderr,"\n\n Error: "); fflush(stderr); perror(msg); exit( 1 ); } #define Plumber( stream ) { if( pipe(stream) == FAIL ) SystemError( "Cannot open pipes." ); } #define Close( stream ) { if( close(stream) == FAIL ) SystemError( "Cannot close stream." ); } #define dup3( stream ) { if( dup( stream ) == FAIL ) SystemError( "Cannot duplicate stream." ); } typedef enum { FAIL = -1, CHILD,EMPTY = 0, SUCCESS } RESULT; typedef enum { INPUT, OUTPUT } STREAM_INDEX; typedef enum { False, True } Bool; typedef int _stream; typedef char* _string,_path; typedef const char _letter; /* the child process execution code(callin the sort function) */ void child( _stream in, _stream out, _string column ); /* reading numbers from the file, multiply the number with the 'column' column, and send it throw pipe. */ int numbersWriter( _string path, _stream out , size_t column, size_t mul ); /* reading Integers from files using row function and system calls */ Bool getInt( _stream in, int* var ); int main(int length, char *params[]){ _stream pipeStream1[2], pipeStream2[2]; int mul,number,counter; if( length < 4 || ( (((*params[2])-'0') < 1) || (((*params[2])-'0') > 3) ) ) SystemError( "Not Enough Parameters Or Illegal Parameters." ); /* opening two pipes. */ Plumber( pipeStream1 ); Plumber( pipeStream2 ); if( fork() == CHILD ){ /* child process - calling the sort function */ Close( pipeStream2[OUTPUT] ); Close( pipeStream1[INPUT] ); child( pipeStream2[INPUT], pipeStream1[OUTPUT], params[2] ); } else{ /* father process */ Close( pipeStream2[INPUT] ); Close( pipeStream1[OUTPUT] ); sscanf(params[3],"%d",&mul); /* multipying the currect column and sending the result to the sort process with a pipe */ numbersWriter( params[1], pipeStream2[OUTPUT],((*params[2])-'0'),mul); Close( pipeStream2[OUTPUT] ); Close( INPUT ); dup3( pipeStream1[INPUT] ); /* printing the result , which we got from the pipe of the sort process */ printf("\n\n Factored, Sorted File : \n"); fflush(stdout); for( counter = 1; getInt( INPUT,&number) == True; ++counter ){ printf("%3d\t",number); fflush(stdout); if( (counter%3) == 0 ) putchar('\n'); } } wait(); WaitForEnter; return 0; } /* reading the next Integer from a stream using row functions and system calls */ Bool getInt( _stream in, int* var ){ char input; ssize_t got = 0; Bool result = False, negative = False,toContinue = True; (*var) = 0; while( toContinue && read(in, &input, 1) > EMPTY ){ if( ((input >= '0' && input <='9') || input == '-' ) ){ result = True; if( input == '-' ) negative = True; else (*var) = (((*var) * 10)+(input-'0')); } else if( result ) toContinue = False; } if( negative ) (*var) = 0 - (*var); return result; } /* multiplying the currect column and sending the result to sort */ int numbersWriter( _string path, _stream out , size_t column, size_t mul ){ _stream input_file; size_t index = 1,counter = 0; int result; Bool flag = True; int written; char s_result[17]; if( ( input_file = open( path, O_RDONLY, 0644 ) ) == FAIL ) SystemError( "Cannot open file." ); while( getInt( input_file, &result ) ){ ++counter; if ( index == column ) result *= mul; sprintf(s_result,"%3d ",result); if( write( out, s_result, strlen(s_result) ) < strlen(s_result) ) SystemError( "Cannot write to a stream." ); if( ++index > 3 ){ index = 1; strcpy(s_result,"\r\n"); } else strcpy(s_result," "); if( write( out, s_result, strlen(s_result) ) < strlen(s_result) ) SystemError( "Cannot write to a stream." ); } fsync( out ); Close( input_file ); return counter; } /* calling the sort function using execlp */ void child( _stream in, _stream out, _string column ){ Close( INPUT ) dup3( in ); Close( OUTPUT ); dup3( out ); if( execlp( "sort","sort","-n","-k",column,NULL) == FAIL ) SystemError ("Cannot execute /usr/bin/sort" ); }