In this case study you will implement a simple logging service built on top of a message queue.
The task is broken into three parts, a message logging server, a library to log messages, and a driver to test the library. You will need to review the lecture notes, and the documentation supplied in Section 5 to implement these programs.
The message logging server should attempt to create the message queue, if this fails then it should terminate with an error message, it should not run if the message queue actually exists ( IPC_EXCL will help here).
Once connected to the message queue, the program should sit in a loop, receiving a mes- sage, and printing it to the stdout . Messages should be formatted:
id: message
where id is the type from the message structure and message is the message field.
The server should shutdown cleanly (i.e. delete the message queue) on receipt of a SIGINT (generated by pressing control and C keys at the same time).
The sample code files logservice.h and logserver.c should form the basis of your solution for this part.
The messaging library consists of two functions, both defined in logservice.h:
int initLogService()
This function should initialise the message queue to log messages to, returning an id if successful, and -1 on error.
This function should not attempt to create the message queue, only attach it to the process.
int logMessage(int id, char * message)
This function logs the message passed as the string message to the log service id . It should return 0 on success and -1 on error.
When sending a message, the function should encode the processes pid into the type field of the message, and the string into the message field.
It is your choice what to do if the message is too long (i.e. longer than MSGCHARS ), sample behaviours include breaking the message up into smaller pieces or simply rejecting it. Whatever the choice, the documentation in the header file should reflect this choice.
The sample code files logservice.h and logservice.c should form the basis of your solution for this part.
This program is used to test the functionality of the library described in Section 2.2. It need not be complex, but is should be able to determine, and report if any errors have occurred.
The sample code files logservice.h and logclient.c should form the basis of your solution for this part.
In addition to the sample code files, two additional files have been provided, a makefile that contains build rules, and a server launch script.
The make utility simplifies the build process for large projects, introductory documen- tation for make is included in the documentation section (Sec. 5). To use make to auto- mate compile process simply type " make " at the terminal (in the same directory as the other files), it will use the rules defined in the makefile to build both the logserver and logclient executables from the source files, and it will also ensure that the launch server.sh script is executable. If none of the source files have changed since the last build (based on their timestamps) the make utility will not rebuild the executables. There should be no need to modify the makefile , its format is a bit fussy so it is safer to download the file from vUWS than type it up.
The launch server.sh script will open the logserver program in a new termi- nal window for you. This script detects the host operating system and performs an equivalent action after this detection. There is nop need to understand how this file achieves its goal.
/* logservice.h -- definitions for the log service */
#ifndef LOGSERVICE_H /* prevent multiple inclusion */
#define LOGSERVICE_H
#include < stdio.h>
#include < stdlib.h>
#include < string.h>
#include < unistd.h>
#include < sys/types.h>
#include < sys/ipc.h>
#include < sys/msg.h>
/* key for the queue*/
#define KEY ftok("logservice.h", ’a’)
/* message structure*/
#define MSGCHARS 255
/* MSGCHARS is the number of characters in the message! */
struct message
{
long type;
char message[MSGCHARS+1]; /* allow it to be a string!*/
};
/* function prototypes*/
int logServiceInit();
/* initialises the log service client, returns a service id*/
int logMessage(int serviceId, char * message);
/* logs the message message to the log service serviceID*/
#endif /* ifndef LOGSERVICE_H */
/* logservice.c -- implementation of the log service*/
#include "logservice.h"
int logServiceInit()
{
int id;
return id;
}
int logMessage(int serviceId,char * message)
{
int rv;
return rv;
}
4.3 logclient.c
/* logclient.c -- implements a simple log service client*/
#include "logservice.h"
int main(int argc,char ** argv)
{
printf("Make me useful too!n");
return 0;
}
4.4 logserver.c
/* logserver.c -- implementation of the log server*/
#include < signal.h>
#include "logservice.h"
int main()
{
printf("Please make me useful!n");
return 0;
}
# makefile -- rules to build OSP workshop C
# to use simply type "make"
# this will build the server and client and launcher script
# note, this is a configuration file for the MAKE utility
# do not try to run it directly
# if typing up the file, the indented lines need to be indented
# with TABS not spaces.
all: logserver logclient
chmod +x launch_server.sh
clean:
rm -f
* .o logserver logclient
logclient: logclient.o logservice.o
logservice.o: logservice.c logservice.h
logserver: logserver.o
logserver.o: logserver.c logservice.h
#!/bin/bash
### This script launches the logserver process in a new window.
### Magic is needed for OSX as I can’t rely on xterm being installed!
### Only works when logged in via the console, not Putty/SSH
### It is not necessary to understand this script!
if [ $(uname) == "Darwin" ]
then
osascript -e ’tell application "Terminal" to do script "cd ’$PWD’; \
./logserver; exit; "’
else
xterm -title "Log Server" -e ’./logserver; \
echo press enter to exit; read junk;’ &
fi