Cli development using ipc shared memory shmget

In: Project Code: PL000004
Share

In this project you will get hands on experience on how to use IPC shared memory to communicate data between two different linux processes. The command to be entered by the user and the server will respond to the command...

Complete this project and update to consider it for requirements and earn certificate.

course thumb

Project Contents

Online courses related to this project


Course description

Learn to develop embedded systems, interfacing electronic peripherals through real time projects and get required practical skills for software jobs



Course description

Learn to develop software solutions for linux environment, implement requirements through real time projects and get required practical skills for software jobs

Client program development, compilation

Client program development.

Command line interface(Cli) development is one kind of project that is required for any product to provide interface to the product customers. It makes the product more user friendly and demand for the product is increased few times more once Cli is developed.

In this project you will get hands on experience on how to use IPC shared memory to communicate data between two different linux processes. The command to be entered by the user, the response to the command given by the server along with the few other parameters are shared between client and server processes using IPC shared memory.

Project is executed in raspberry pi with debian linux operating system loaded on it. However you can execute this project in any linux distribution including linux virtual machines. Following are the learnings from this project:

Client program development, compilation

Client program development.
client.c: client program to take user input command and get response from server.

/*
 * Program: client.c
 * Purpose: Client side code for cli development project
 */
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "fcntl.h"
#include "unistd.h"
#include "sys/types.h"
#include "sys/wait.h"
#include "stdint.h"
#include "sys/mman.h"
#include "sys/stat.h"
#include "semaphore.h"
#include "sys/mman.h"
#include "sys/stat.h"
#include  "sys/types.h"
#include  "sys/ipc.h"
#include  "sys/shm.h"

#define CMD_LENGTH 100 /* Max command length */
#define KEY 0x5444 /* Shared memory key */
#define SIZE 4096 /* Size of the shared memory */

void getCmd(char *);

struct cli {
  int wr_update;
  int rd_update;
  int ack;
  char cmd[100];  /* pointer to shared memory obect */
  char response[100];
};
int main(){
  struct cli *p;

  /* name of the shared memory object */
  const char* name = "OS";
  /* shared memory file descriptor */
  int shm_fd;
  /* create the shared memory object */
  shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666);
  /* configure the size of the shared memory object */
  ftruncate(shm_fd, SIZE);
  /* memory map the shared memory object */
  shm_fd = shmget(KEY, sizeof(struct cli), IPC_CREAT | 0666);
  if (shm_fd < 0) {
    printf("shmget error\n");
    exit(1);
  }
  p = shmat(shm_fd, NULL, 0);  /* attach */
  if (p == 0) {
    printf("*** shmat error (server) ***\n");
    exit(1);
  }
  p->wr_update = 0;
  p->rd_update = 1;
  p->ack = 0; 
  while (1) {
    char cmd[20];
    getCmd(cmd);
    printf("Input command:%s\n",cmd);
    if(strcasecmp(cmd,"exit\n") == 0) {
      printf("Terminating client program\n");
      exit(0);
    } else {
      if(p->wr_update == 0 && p->rd_update == 1) {
        /* write to the shared memory object */
        sprintf(p->cmd, "%s\n", cmd);
        p->wr_update = 1;
        p->rd_update = 0;
        newConn:
        if(p->ack == 1) {
          printf("%s", p->response);
          memset(p->response, 0, sizeof(p->response));
          p->ack = 0;
        } else {
          goto newConn;
        }
      }
    }
  }
  /* remove semaphores*/
  shmdt(p);
  close(shm_fd);
  return 0;
}
void getCmd(char *name){
  printf("Enter command to execute or exit to exit the cli :");
  fgets(name,CMD_LENGTH,stdin);
}

Let's go through the client code written in client.c. We have defined a structure cli which is shared between client and server processes. String cmd is declared inside struct cli to take command from user. String response is declared inside struct cli to collect response from server and then send it to the client. wr_update, rd_update, ack are the three parameters used to syncronize the events between client and server processes. Then we have created a shared memory with name "OS" and memory mapped it using shmget using a shared memory KEY.

To start with we have initialized wr_update to 0, rd_update to 1, ack bit to 0. In a while loop we are waiting for user command using a function getCmd which uses fgets to take user input. If user enters exit command program terminates through exit(0).

For any other command other than exit, program writes the command into the cmd string which is shared by the server program. Once the write is completed, it updates the wr_update status to 1, rd_update status to 0. We will program the server later in this project such a way that it will execute the command once the update is received.

The last thing we are doing in client program is waiting for ack bit to be 1. This update will be received from server. Once server executes the command and writes the response it updates ack bit from 0 to 1. After that update only we will go and retrieve the response.

Client program compilation.

To Read Full Article

Start any course from the following
Share