/* file:		child1.c
 * author:		Robert S. Laramee
 * class:		cs720/820
 * date started:  	27 Jan 98
 * date finished:	27 Jan 98
 * project:		assignment 1
 * description:		This program opens the data file and reads the
 *                      elements of the specified row of matrixA and
 * matrixB from the data file.  It then computes the sum of the specified
 * row and writes it to output file add.out.
 *
 *  argv[0] = child1    -name of executable (child1)
 *  argv[1] = mat.dat   -data filename
 *  argv[2] = x         -current row number
 *  argv[3] = x         -number of columns in matrices
 */

#include       /* for printf(), scanf()       */
#include 	/* for malloc(), realloc()     */

void main(int argc, char *argv[]) {

   FILE *mat_ptr;       /* pointer to mat.dat file      */
   FILE *add_ptr;       /* pointer to add.out file      */
   int *int_ptr;	/* pointer to allocated int	*/
   int i=0, j=0, data, offset;	
   int num_cols = atoi(argv[3]);

/*   printf("\n child process 1 with ID = %ld", (long)getpid()); */

   /* Start off by allocating storage for an array of 1 integer using
    * malloc() and saving the returning addres in 'int_ptr'.  Check that this
    * has been done correctly with an 'if' test and a comparison with the
    * value NULL
    */

   if ((int_ptr = malloc (sizeof(int))) == NULL) {
      printf("\n no memory for malloc() \n");
      exit(1);
   }

   if ( (mat_ptr = fopen(argv[1], "r")) == NULL) {
      printf("\n Cannot open data file for reading \n");
      exit(1);
   }

   /* move to appropriate position in file. The offset is measured in 
    * characters and is row_num * num_cols * 4 (4 characters per entry) 
    */
   offset = atoi(argv[2]) * atoi(argv[3]) * 4;
   fseek(mat_ptr, offset, SEEK_SET);

   /* Now commence reading integer values from the file only from the
    * row we are interested in.  Once a value has been read, copy it to
    * the dynamically allocated array pointed to by 'int_ptr'.  Note the
    * 'int_ptr' is not changed, since its value (an address) will be
    * needed later when the storage allocated to the array is released.
    * Once this has been done resize the array using realloc() to include
    * storage for one more integer and repeat.
    */

   for ( j=0; j<2*num_cols; j++) {
      fscanf(mat_ptr, "%d ", &data);
      int_ptr[i++] = data;
      int_ptr = realloc(int_ptr, (i + 1) * sizeof(int));
   }

   /* open the output file, go to the end of it, and write the
    * addition of the current row.
    */
   if ( (add_ptr = fopen("add.out", "a+")) == NULL) {
      printf("\n Cannot open file add.out for reading/writing \n");
      exit(1);
   }
   fseek(add_ptr, 0L, SEEK_END);
   for( i=0; i < num_cols; i++) {
      fprintf(add_ptr," %d", int_ptr[i]+int_ptr[i+num_cols]);
   }
   fprintf(add_ptr,"\n");
   
   if (fclose(mat_ptr))
      printf("\n error closing data file \n");
   if (fclose(add_ptr))
      printf("\n error closing add.out \n");
   free(int_ptr);		/* no memory leaks here */
   exit(0);
}