Diff of /SimpleShmExample/main.c [000000] .. [d172b5]  Maximize  Restore

Switch to side-by-side view

--- a
+++ b/SimpleShmExample/main.c
@@ -0,0 +1,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");
+}