Hi all,

This patch adds shm_open() and shm_unlink() to librt.
For my own purposes, I have git'ed uclibc and made the patch from there, so let me know if you need it in another format.

The included testapp simply creates shared memory area in a parent process, writes test data to it and opens and verifies the data in a forked child process.

Thanks,
Mikael

Carmelo AMOROSO skrev:
Mikael Lund Jepsen, ICCC wrote:
Hi all,
I cannot see the shm_open / shm_unlink functions implemented in librt.
Is there any reason (bloat, ?) for not including these?

as simply it is reported in uClibc_vs_SuSv3.txt, they are optional and simply not implemented until now.

I've tried taking shm_open.c and shm_unlink.c from newlib and dropped them in librt, and so far it seems to be working as expected. I have not done any extensive tests though.

Any interest?

please post your patches as well test cases for review and inclusion.
Thanks
Mikael
cheers,
carmelo
_______________________________________________
uClibc mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/uclibc



--


Mikael Lund Jepsen, Software Engineer

ICCC A/S, Telegrafvej 5 B, 2750 Ballerup, DENMARK

Phone: +45 44 86 04 00
Direct: +45 44 86 04 25
Fax: +45 44 86 03 99
   
Email: [email protected]
Web: www.iccc.dk
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/wait.h>


char Commonname[] = "MyTestMem";
int TestData[11] = {0,1,2,3,4,5,6,7,8,9,10};

int main(void) {
        int pfds[2];
        pid_t pid;
        int hCommon;
        int TestdataFails = 0;
        char *pTestData;
        unsigned int i;
        char buf[30];
        int rv;

        pipe(pfds);

        switch(pid = fork()) {
        case -1:
                perror("fork");
                exit(1);        // parent exits

        case 0:
                // Child

                // wait for parent
                read(pfds[0], buf, 5);
                
                hCommon =  shm_open(Commonname, O_RDWR, DEFFILEMODE);
                if (hCommon == -1) {
                        perror("CHILD - shm_open(existing):");
                        exit(1);
                } else {
                        pTestData = mmap(0, sizeof(TestData), PROT_READ + 
PROT_WRITE, MAP_SHARED, hCommon, 0);
                        if (pTestData != MAP_FAILED) {
                                for (i=0; i < sizeof(TestData); i++) {
                                        if (pTestData[i] != TestData[i]) {
                                                printf("%-40s: Offset %d, local 
%d, shm %d", "Compare memory error", i, TestData[i], pTestData[i]);
                                                TestdataFails++;
                                        }
                                }
                                if (TestdataFails == 0)
                                        printf("%-40s: %s\n", "Compare memory", 
"Success");

                                munmap(pTestData, sizeof(TestData));
                        }
                }
                exit(0);

        default:
                // Parent
                hCommon = shm_open(Commonname, O_RDWR+O_CREAT+O_EXCL, 
DEFFILEMODE );
                if (hCommon == -1) {
                        perror("PARENT - shm_open(create):");
                } else {
                        if ((ftruncate(hCommon, sizeof(TestData))) == -1)
                        {
                                printf("%-40s: %s", "ftruncate", 
strerror(errno));
                                shm_unlink(Commonname);
                                return 0;
                        }

                        pTestData = mmap(0, sizeof(TestData), PROT_READ + 
PROT_WRITE, MAP_SHARED, hCommon, 0);
                        if (pTestData == MAP_FAILED)
                        {
                                perror("PARENT - mmap:");
                                if (shm_unlink(Commonname) == -1) {
                                        perror("PARENT - shm_unklink:");
                                }
                                return 0;
                        }
                        for (i=0; i <sizeof(TestData); i++)
                                pTestData[i] = TestData[i];

                        // signal child
                        write(pfds[1], "rdy", 5);
                        // wait for child
                        wait(&rv);

                        // Cleanup
                        munmap(pTestData, sizeof(TestData));
                        if (shm_unlink(Commonname) == -1) {
                                perror("PARENT - shm_unklink:");
                        }
                }
        }
        return 0;
}
commit 941e902888017dcd798c4ba61d5a702085d806f9
Author: Mikael Lund Jepsen <[email protected]>
Date:   Wed Jan 14 20:17:30 2009 +0100

    Add shm_open.c and shm_unlink.c to librt.
    
    Original source: sourceware.org/newlib, CVS snapshot 2009-01-14

diff --git a/librt/shm_open.c b/librt/shm_open.c
new file mode 100644
index 0000000..cb92c3a
--- /dev/null
+++ b/librt/shm_open.c
@@ -0,0 +1,48 @@
+/* shm_open - open a shared memory file */
+
+/* Copyright 2002, Red Hat Inc. */
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <limits.h>
+
+int
+shm_open (const char *name, int oflag, mode_t mode)
+{
+  int fd;
+  char shm_name[PATH_MAX+20] = "/dev/shm/";
+
+  /* skip opening slash */
+  if (*name == '/')
+    ++name;
+
+  /* create special shared memory file name and leave enough space to
+     cause a path/name error if name is too long */
+  strlcpy (shm_name + 9, name, PATH_MAX + 10);
+
+  fd = open (shm_name, oflag, mode);
+
+  if (fd != -1)
+    {
+      /* once open we must add FD_CLOEXEC flag to file descriptor */
+      int flags = fcntl (fd, F_GETFD, 0);
+
+      if (flags >= 0)
+        {
+          flags |= FD_CLOEXEC;
+          flags = fcntl (fd, F_SETFD, flags);
+        }
+
+      /* on failure, just close file and give up */
+      if (flags == -1)
+        {
+          close (fd);
+          fd = -1;
+        }
+    }
+
+  return fd;
+}
diff --git a/librt/shm_unlink.c b/librt/shm_unlink.c
new file mode 100644
index 0000000..cf259c6
--- /dev/null
+++ b/librt/shm_unlink.c
@@ -0,0 +1,28 @@
+/* shm_unlink - remove a shared memory file */
+
+/* Copyright 2002, Red Hat Inc. */
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <string.h>
+#include <limits.h>
+
+int
+shm_unlink (const char *name)
+{
+  int rc;
+  char shm_name[PATH_MAX+20] = "/dev/shm/";
+
+  /* skip opening slash */
+  if (*name == '/')
+    ++name;
+
+  /* create special shared memory file name and leave enough space to
+     cause a path/name error if name is too long */
+  strlcpy (shm_name + 9, name, PATH_MAX + 10);
+
+  rc = unlink (shm_name);
+
+  return rc;
+}
_______________________________________________
uClibc mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/uclibc

Reply via email to