[d172b5]: / SimpleShmExample / main.c  Maximize  Restore  History

Download this file

189 lines (164 with data), 4.7 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>

#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>

#include <sys/mman.h>
#include <sys/types.h>

#include <stdint.h>
 #include <string.h>

 void printUsage();

 typedef int bool;
 #define true 1
 #define false 0

int main( int argc, const char* argv[] )
{
  // args parsing
  bool xGet = false;
  bool xSet = false;
  bool xReset = false;
  uint16_t uiSetValue = 0;
  {
    // pares args
    char opt;
    while((opt = getopt(argc, (char * const*)argv, "srgh")) != -1)
      {
          switch(opt)
          {
              case 's': // set
                  xSet = true;
                  break;
              case 'r': // reset
                  xReset = true;
                  break;
              case 'g': // get
                  xGet = true;
                  break;
              case 'h': // help
                  printUsage();
                  return 0;
                  break;
              default:
                  printf("invalid opt: %s\n", opt);
                  printUsage();
                  return -1;
          }
      }

      // check that only one option is used
      if ((xGet && xSet) || (xGet && xReset) || (xSet && xReset))
      {
        printf("Only one option at a time!\n");
        printUsage();
        return -2;
      }

      // if no option selected, assume get
      if (!(xGet || xSet || xReset))
        xGet = true;

      // optind is for the extra arguments
      // which are not parsed
      if (!xSet && optind < argc)
      {
        // only set expects additional arguments
        printf("unexpected extra argument: %s\n", argv[optind]);
        printUsage();
        return -3;
      }
      else if ((optind + 1) < argc)
      {
        // set only expects one extra argument
        printf("unexpected extra argument: %s\n", argv[optind+1]);
        printUsage();
        return -4;
      }
      else if (xSet)
      {
        printf("extra argument for set: %s\n", argv[optind]);
        if (!sscanf(argv[optind], "%hd", &uiSetValue))
        {
          printf("unable to parse the number: %s\n", argv[optind]);
          return -5;
        }
      }
  }

/* ********************************************
 * Actual shared memory code
 **********************************************/

  char pszName[] = "CodesysShared";
  uint16_t uiCounter = 0;
  size_t shmSize = sizeof(uiCounter);
  int shmfd;  // shared memory handle
  bool xShmWasCreated = false;
  void *pshm = NULL;
  // try to open shm
  {
    shmfd = shm_open(pszName, O_RDWR, S_IRWXU | S_IRWXG);

    if (shmfd < 0)
  		{
  			/* creating a new shared memory object  because it does not exist*/
        printf("creating new shm\n");
  			shmfd = shm_open(pszName, O_CREAT | O_RDWR, S_IRWXU | S_IRWXG); /* returns a file handle -- O_EXCL */
        xShmWasCreated = true;
  		}

    if (shmfd < 0)
    {
      printf("failed to execute shm_open() : %d\n", shmfd);

      return 1;
    }

    // adjust the mapped file size
    if (ftruncate(shmfd, shmSize) < 0)
  		{
        printf("ftruncate() failed\n");
        close(shmfd);
        return 2;
      }

      /* requesting the shared segment    --  mmap()
  		void * mmap(void *start, size_t length, int prot , int flags, int fd, off_t offset); */
  		pshm = mmap(0, shmSize, PROT_READ | PROT_WRITE, MAP_SHARED, shmfd, 0);
      if (pshm == MAP_FAILED)
      {
        printf("mmap() failed: %s\n", strerror(errno));
        close(shmfd);
        return 3;
      }

      printf("shared memory open\n");

      if (xShmWasCreated)
      {
        /* shared memory is new, so set it to 0 */
        memset(pshm,0,sizeof(uiCounter));
        printf("Shm was new, set it to 0.\n");
      }
  }
/* *************************************
 * Accessing the shared memory
 ***************************************/

    uint16_t *pCounter = (uint16_t *)pshm;

    // always read the value and print it
    uiCounter = *pCounter;
    printf("counter is %d\n", uiCounter);

    if (xReset)
    {
      uiCounter = 0; // set local copy
      *pCounter = uiCounter; // set actual shm
      printf("reset the counter!\n");
    }
    else if (xSet)
    {
      uiCounter = uiSetValue; // set local copy
      *pCounter = uiCounter; // set actual shm
      printf("Set the counter to: %d\n", uiCounter);
    }

    // close the shared memory
    munmap(pshm,shmSize);
    close(shmfd);

    return 0;
}

void printUsage()
{
  printf("program [-g | -s number | -r | -h]\n");
  printf("default: -g\n");
  printf("-g        : get counter\n");
  printf("-s number : set counter to number\n");
  printf("-r        : reset counter\n");
  printf("-h        : print usage\n");
}