Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

Overview: 1. You are to write two programs, interface and db. After initialization, interface will use the fork system call and an exec system call

Overview:

1. You are to write two programs, interface and db. After initialization, interface will use the fork system call and an exec system call to start the execution of db. Interface will accept commands from the console and send them to db for execution. After executing the command, db will send the output to interface for display on the console.

2. Pipes: interface will need to create the pipes to be used for communication between itself and db prior to doing the fork. Use two pipes, one for sending commands to db and one for sending the response to interface.

3. Interface: In addition to tasks described elsewhere, interface must pass the pipe file descriptor values to db. Use the arguments on the exec command for this purpose. Interface should also detect the final exit status of db and display an appropriate message.

4. DB: When db initializes, it must do two things before entering its loop accepting commands. First, it must initialize an array of structures (records) using the data in a local file called accountData.

This file must contain data for at least twelve records. Second, it should display the contents of the array so it is easy to verify that the initialization occurred correctly. The records will keep track of a set of bank accounts. Each structure in the array is to consist of the following fields:

id: this is the identifier of the account. It is to be a long integer.

checkNumber: the check (or transaction) number (int).

amount: The amount withdrawn from the account (float).

date: The date of the transaction(char).

You are to create and use a typedef for the record structure.

5. accountData: each line of this ASCII file is to contain the data for one record of the array of structures. Each line is expected to be in the form:

id checkNumber date amount

where a single space is used as a delimiter.

6. Makefile: Write a makefile to control the compilation of your programs.

7.Commands: Four commands must be processed:

account,

This is to compute the total value of all transactions identified by the label .

list

This will list all of the transactions ordered first by id and then for each id ordered by increasing date.

(Note: it is assumed that some sorting will have to be performed; the elements must be initialized in a different order.)

date,

This is to compute the total value of all transactions that occurred on the given date.

exit

After processing this command, db should terminate in a normal manner. After detecting the termination of db, interface should print relevant information and exit normally.

8. System calls: You should view this exercise as an opportunity to try out various system calls. Detailed documentation of the system calls can be found in the associated man pages. At a minimum, you are expected to use the following system calls: fork, some type of exec call (such as execve), pipe, read, write, exit, waitpid, close. In addition your code is to check the response from the system calls for errors, display an appropriate error message and take appropriate action. In many cases that action may be just to call exit with a unique number selected.

9. Readability: Your program must be written using good C programming conventions:

Variable names and function names should be descriptive of what they represent.

Use indentation to show the structure of the program. Typically this means using indentation with for, while, do-while, if, and switchstatements as well as indenting the body of functions. Indentation should show the nesting level of the statements involved.

Include some in-line documentation to give a high level view of what the program and groups of statements is/are doing.

Sample output:

element[0]: id = 1234567, check Number: 102, date: 08/11/14, amount: 4.00

element[1]: id = 1234567, check Number: 101, date: 08/14/14, amount: 14.00

element[2]: id = 3456787,check Number: 9873, date: 08/30/14, amount: 100.00

element[3]: id = 1234567, check Number: 100, date: 08/16/14, amount: 35.00

element[4]: id = 3456787,check Number: 9874, date: 09/30/14, amount: 4.00

element[5]: id = 12345, check Number: 1010, date: 09/01/14, amount: 34.00

element[6]: id = 1001001, check Number: 905, date: 08/14/14, amount: 9.00

element[7]: id = 1001001, check Number: 903, date: 08/30/14, amount: 11.00

element[8]: id = 12345,check Number: 1001, date: 09/14/14, amount: 16.00

element[9]: id = 12345, check Number: 1111, date: 08/24/14, amount: 2.00

element[10]: id = 1234, check Number: 1112, date: 08/31/14, amount: 44.00

element[11]: id = 1001001, check Number: 902, date: 09/25/14, amount: 19.00

Input command (account,id | list| date,mm/dd/yy | exit):

account,1001001

response: Total for account 1001001: 39.00

Input command (account,id | list| date,mm/dd/yy | exit):

date,08/14/14

response: Total on date 08/14/14: 23.00

Input command (account,id | list| date,mm/dd/yy | exit):

account,1234567

response: Total for account 1234567: 53.00

Input command (account,id | list| date,mm/dd/yy | exit):

exit

response: db complete.

interface: child process (212) completed.

interface: child process exit status = 0.

interface: Complete.

Hints:

Some of the library string functions may be useful: strchr, strcmp, strncmp, strncpy.

In the end, you should have (.c and .h files), makefile, and data file (accountData).

***Here is the makefile(.txt)***

all: Interface db

interface: Interface.c

gcc Interface.c -o Interface

db: db.c

gcc db.c -o db

clean:

rm -f Interface.c

rm -f db.c

***accountData(.txt) file***

1234567 102 08/11/14 4.00 1234567 101 08/14/14 14.00 3456787 9873 08/30/14 100.00 1234567 100 08/16/14 35.00 3456787 9874 09/30/14 4.00 12345 1010 09/01/14 34.00 1001001 905 08/14/14 9.00 1001001 903 08/30/14 11.00 12345 1001 09/14/14 16.00 12345 1111 08/24/14 2.00 1234 1112 08/31/14 44.00 1001001 902 09/25/14 19.00

***Interface.c file***

#include #include #include #include #include

#include

#define BUFFER_SIZE 2048

void clearBuffer(char * input); void errcheck(int err);

int main() { int DBreturn = -1; int err; int Status=0; int writeError, readError; int toDB[2]; int toInterface[2]; char args1[50]; char args2[50];

char ReadBuffer[BUFFER_SIZE+1]; //Input char WriteBuffer[BUFFER_SIZE+1]; //Cmd

int DBpid;

//Create Pipes pipe(toDB); pipe(toInterface); //fork child process DBpid = fork();

if(DBpid == -1){ printf("There was an error on fork. Error Number: %d ", errno); exit(-1); } else if (DBpid == 0){ //in child process //Close unused pipe ends close(toDB[1]); close(toInterface[0]); printf("Child ID: %d toDB :%d toInt :%d ", getpid(),toDB[0], toInterface[1]); //Assign args sprintf(args1,"%d", toDB[0]); sprintf(args2,"%d", toInterface[1]); //Execute DB Program err = execl("./DB",args1,args2,NULL);

if(err == -1){ printf("It looks like there was an issue with starting DB "); printf("Error Number :%d", errno); exit(-1); }

//DB is initialized. }else{ // in Parent process //Close unused pipe ends close(toDB[0]); close(toInterface[1]);

//Pipes are established //Expecting message from DB with a success. printf("Reading from DB "); //debugging readError = read(toInterface[0],ReadBuffer, 99); printf("Response: %s", ReadBuffer); clearBuffer(ReadBuffer); errcheck(readError); //Begin menu loop int Done = 0; while(Done == 0 ){

printf("Please supply a command( 'account, id' | list | date,mm/dd/yy | exit) :"); //recieve input from user, send to DB. clearBuffer(WriteBuffer); scanf("%s", WriteBuffer); writeError = write(toDB[1], WriteBuffer, BUFFER_SIZE); errcheck(writeError); //Read Response from DB readError = read(toInterface[0], ReadBuffer, BUFFER_SIZE); errcheck(readError); printf("Response: %s ", ReadBuffer); //Check for exit return by DB if(atoi(ReadBuffer) == 1){ Done = 1; } clearBuffer(ReadBuffer); } //Wait for child process to finish; err = waitpid(-1, &Status ,0); errcheck(err); printf("Goodbye! ");

}//End of Parent Instructions

return 0; //Exit }

void clearBuffer(char *input){ int i = 0; for(i; i < BUFFER_SIZE; i++){ *(input+i) = '\0'; } }

void errcheck(int err){

if(err == -1){ printf("It looks like there was an issue..."); printf("Error Number :%d ", errno); exit(-1); } }

***db.c file***

#include #include #include

#define RL 1000 //Record Limit. #define BUFFER_SIZE 2048 //Maximum BufferSize

//Struct declaration for records. typedef struct { long int id; //account number int checkNumber; //check Number char date[9]; //Date mm/dd/yy'\0' float amount; //Dollar amount xx.xx }record;

//Functions void clearBuffer(char *input); void sort(record *recs, int count); void printRecords(record *records, int count); void errcheck(int err); float getTotal(long int account, const record *recs, int count); float getDateTotal(char * date, const record * recs, int count);

//Expects 2 integers for program execution. int main(int argc,char **argv){ //Initializations for communication char writeBuffer[2048]; char readBuffer[2048]; char Cmd[100]; int toDB[2]; int toInterface[2]; int writeError; int readError;

//Initialize for file read. FILE *fd;

//assign pipe values from start; sscanf(argv[0],"%d",&toDB[0]); sscanf(argv[1],"%d",&toInterface[1]);

//Open the accountData file. fd = fopen("accountData","r"); //Initialize array to hold records. record records[RL+1];

int i =0; int numRecords; int err; //read records from file. for(i=0; !feof(fd) && i err = fscanf(fd,"%ld %d %s %f ",&records[i].id, &records[i].checkNumber, records[i].date, &records[i].amount); if(err ==-1){ printf("Error in processing file... Error:%d ",errno); exit(-1); } printf("[%d]:%ld %d %s %.2f ",i,records[i].id, records[i].checkNumber, records[i].date, records[i].amount); numRecords++; } //write records to buffer sort(records, numRecords); clearBuffer(writeBuffer);

//records have been read in, sort them for further displays

sprintf(writeBuffer,"All records added successfully. - DB Initialized - "); writeError = write(toInterface[1],writeBuffer,99); errcheck(writeError); //ready to recieve input from interface. //Create call structure for different calls from interface. int Done = 0; while(Done == 0){

readError = read(toDB[0],readBuffer, BUFFER_SIZE); clearBuffer(writeBuffer); errcheck(readError); if(strncmp(readBuffer,"\0",1) == 0){wait(10);} else if(strncmp(readBuffer,"account",7)== 0 ){ long int account; float amount; char accountch[12]; int i; int j = 0; //extract account number for (i = 8; i < 20; i++){ accountch[j++] = readBuffer[i]; } sscanf(accountch,"%ld",&account); clearBuffer(readBuffer);

//Total up the amount for the given account number. amount = getTotal(account, records, numRecords);

//Write account amount to the buffer in the formatted string. clearBuffer(writeBuffer); sprintf(writeBuffer,"total for %ld = %.2f. ",account,amount); writeError = write(toInterface[1],writeBuffer,99); errcheck(writeError); } else if (strncmp(readBuffer,"list",4)== 0 ){ clearBuffer(readBuffer); int done = 0; if(numRecords ==0){done = 1;} int i=0; int offset = 0; //loop through records each to buffer clearBuffer(writeBuffer); for(i = 0; (i < numRecords) && (done != 1); i++){ offset += sprintf(writeBuffer+offset,"[%d]:%ld %d %s %.2f ",i,records[i].id ,records[i].checkNumber , records[i].date, records[i].amount);

} //Write entire buffer writeError = write(toInterface[1],writeBuffer,BUFFER_SIZE); errcheck(writeError); } else if(strncmp(readBuffer, "date",4) == 0){ float amount; char date[12]; int i; int j = 0; //Extract date from the buffer for (i = 5; i < 17; i++){ date[j++] = readBuffer[i]; }

clearBuffer(readBuffer); //get total for the given date amount = getDateTotal(date, records, numRecords); //write total to buffer clearBuffer(writeBuffer); sprintf(writeBuffer,"total for %s = %.2f. ",date,amount); writeError = write(toInterface[1],writeBuffer,99); errcheck(writeError);

} else if(strncmp(readBuffer, "exit",4) == 0){ //Command from interface is exit. //send 1 down the pipe to terminate parent loop. clearBuffer(writeBuffer); sprintf(writeBuffer,"%d",1); writeError = write(toInterface[1],writeBuffer,99); errcheck(writeError); Done = 1; } else{ //Unknown command, clear buffer and try again to recieve input from the user. clearBuffer(writeBuffer); sprintf(writeBuffer,"DB did not understand the command... "); writeError = write(toInterface[1],writeBuffer,99); errcheck(writeError); } clearBuffer(readBuffer); }

return 0; } /////////////////////////FUNCTION LIST////////////////////////////////////////// void clearBuffer(char *input){ int i = 0; for(i; i < BUFFER_SIZE; i++){ *(input+i) = '\0'; } }

void sort( record *recs, int count){ //Simple sort takes in pointer to array of record.

int i = 0; int j = 0; int position;

for ( i = 0 ; i < (count -1) ; i++ ) { position = i;

for ( j = i + 1 ; j < count ; j++ ) { if (recs[position].id > recs[j].id ) //If Id is greater, swap. { position = j; } if ( recs[position].id == recs[j].id ){ //sort by date, id's are equal int k = 0; char y[2],d[2],m[2]; char jy[2],jd[2],jm[2]; int x=0,w=0,z=0; //First, extract the year, day, and month from the date. for (k = 0; k < 8;k++){ if(k == 0||k ==1){//Month m[x]= recs[position].date[k]; jm[x]= recs[j].date[k]; x++; } if(k == 3 ||k == 4){//Day d[w]= recs[position].date[k]; jd[w]= recs[j].date[k]; w++; } if(k == 6 ||k == 7){//Year y[z]= recs[position].date[k]; jy[z]= recs[j].date[k]; z++; } } if(strncmp(y,jy,2)>0){//Compare if y > jy, will evaluate true

position = j; break; } else if (strncmp(y,jy,2)==0){//years equal, continue

if(strncmp(m,jm,2)>0){ position = j; break; } else if(strncmp(m,jm,2)==0){//months equal, continue

if(strncmp(d,jd,2)>0){ position = j; } } } } } //swap actual struct array elements. if ( position != i ) { record temp; temp = recs[i]; recs[i] = recs[position]; recs[position] = temp; } }

}

void printRecords(record *records, int count){

int i = 0; for(i; i < count; i++){ printf("%ld %d %s %.2f ",records[i].id, records[i].checkNumber, records[i].date, records[i].amount); } } //Wrote function to minimize the space by this check. void errcheck(int err){

if(err == -1){ printf("It looks like there was an issue..."); printf("Error Number :%d ", errno); exit(-1); } } //Takes and account number and accumulates the total for the give date. float getTotal(long int account, const record * recs, int count ){ float total = 0; int i; for(i=0; i< count;i++){

if(recs[i].id == account){ total+=recs[i].amount; } } return total; } //Takes in a date: mm/dd/yy, and accumulates the total for the given date float getDateTotal(char * date, const record * recs, int count ){ float total = 0; int i; for(i=0; i< count;i++){

if(strncmp(recs[i].date,date,8)==0){ total+=recs[i].amount; } } return total; }

*** The following programs and the textfile and the makefile are included. However, I am unable to get the program to get the output that is required. Within the guidelines of the question, there is a "sample output" section. In addition, there are guidelines that highlight what must be done in order to get the overall programs to work. However, I am unable to get this working. The overview of this question is on the top. When compiling, you first input "make", then all you have to do is just input "Interface". However, I get something completely different and thus, it does not do what the question asks. I have been at this program for a long time. If you could either correct the provided code or submit a different intake, that would be great. All of the descriptions are on the top if you have any questions. Please help. ***

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image_2

Step: 3

blur-text-image_3

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Logidata+ Deductive Databases With Complex Objects Lncs 701

Authors: Paolo Atzeni

1st Edition

354056974X, 978-3540569749

More Books

Students also viewed these Databases questions

Question

How is the NDAA used to shape defense policies indirectly?

Answered: 1 week ago