[PATCH] librt: Add shm_open and shm_unlink + testcase

Bernhard Reutner-Fischer rep.dot.nop at gmail.com
Mon Jun 8 08:15:40 UTC 2009


On Mon, Jun 08, 2009 at 10:10:09AM +0200, Mikael Lund Jepsen, ICCC wrote:
> Bernhard Reutner-Fischer wrote:
>> I suggest you base off the (completely untested) b32dd708df63d90f9d755b6c0de2588200e432ca
>> Please also add testsuite entries.
>>   
> Apart from the use of the GNU extension, this is very similar to what I  
> had, but I do have one comment though:
> There is no check on the return value of snprintf, so if name is  
> (silently) truncated, two different names may trunctate to the same  
> filename - and the user will never know what hit him. Checking if  
> snprintf returned NAME_MAX or more and then setting ENAMETOOLONG should  
> do the trick...
>
> Even though the man page of shm_open does not mention it, I think it  
> would be nice if we set ENOMEM if malloc fails, since dynamic allocation  
> is special to our implementation.

I think that malloc would have set ENOMEM already so i will drop that bit.
>
> I've included a patch with my suggested changes and my testsuite entry.

Will apply shortly. Thanks!
>
> TIA,
> Mikael

>>From 97c08e96db0deb037626cd90470e299707379849 Mon Sep 17 00:00:00 2001
>From: Mikael Lund Jepsen <mlj at iccc.dk>
>Date: Mon, 8 Jun 2009 10:02:48 +0200
>Subject: [PATCH] Set errno for shm_open and shm_unlink and add tests to testsuite
>
>Untested
>
>Signed-off-by: Mikael Lund Jepsen <mlj at iccc.dk>
>---
> librt/shm.c          |    9 ++++-
> test/librt/Makefile  |    6 +++
> test/librt/shmtest.c |  102 ++++++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 116 insertions(+), 1 deletions(-)
> create mode 100644 test/librt/Makefile
> create mode 100644 test/librt/shmtest.c
>
>diff --git a/librt/shm.c b/librt/shm.c
>index 637e945..fce83c6 100644
>--- a/librt/shm.c
>+++ b/librt/shm.c
>@@ -42,13 +42,20 @@ static char* get_shm_name(const char*name)
> 		return NULL;
> #else
> 	path = malloc(NAME_MAX);
>-	if (path == NULL)
>+	if (path == NULL) {
>+		__set_errno(ENOMEM);
> 		return NULL;
>+	}
> 	i = snprintf(path, NAME_MAX, _PATH_SHM "%s", name);
> 	if (i < 0) {
> 		free(path);
> 		return NULL;
> 	}
>+	if (i >= NAME_MAX) {
>+		free(path);
>+		__set_errno(ENAMETOOLONG);
>+		return NULL;
>+	}
> #endif
> 	return path;
> }
>diff --git a/test/librt/Makefile b/test/librt/Makefile
>new file mode 100644
>index 0000000..362d5d5
>--- /dev/null
>+++ b/test/librt/Makefile
>@@ -0,0 +1,6 @@
>+# uClibc shm tests
>+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
>+
>+include ../Test.mak
>+
>+LDFLAGS_shmtest := -lrt
>diff --git a/test/librt/shmtest.c b/test/librt/shmtest.c
>new file mode 100644
>index 0000000..8fb166d
>--- /dev/null
>+++ b/test/librt/shmtest.c
>@@ -0,0 +1,102 @@
>+/* Copyright (C) 2009 Mikael Lund Jepsen <mlj at iccc.dk>
>+ *
>+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
>+ */
>+
>+#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 shared_name[] = "/sharetest";
>+int test_data[11] = {0,1,2,3,4,5,6,7,8,9,10};
>+
>+int main(void) {
>+	int pfds[2];
>+	pid_t pid;
>+	int fd;
>+	int test_data_fails = 0;
>+	char *ptest_data;
>+	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);
>+
>+		fd =  shm_open(shared_name, O_RDWR, DEFFILEMODE);
>+		if (fd == -1) {
>+			perror("CHILD - shm_open(existing):");
>+			exit(1);
>+		} else {
>+			ptest_data = mmap(0, sizeof(test_data), PROT_READ + PROT_WRITE, MAP_SHARED, fd, 0);
>+			if (ptest_data != MAP_FAILED) {
>+				for (i=0; i < sizeof(test_data); i++) {
>+					if (ptest_data[i] != test_data[i]) {
>+						printf("%-40s: Offset %d, local %d, shm %d", "Compare memory error", i, test_data[i], ptest_data[i]);
>+						test_data_fails++;
>+					}
>+				}
>+				if (test_data_fails == 0)
>+					printf("%-40s: %s\n", "Compare memory", "Success");
>+
>+				munmap(ptest_data, sizeof(test_data));
>+			}
>+		}
>+		exit(0);
>+
>+	default:
>+		// Parent
>+		fd = shm_open(shared_name, O_RDWR+O_CREAT+O_EXCL, DEFFILEMODE );
>+		if (fd == -1) {
>+			perror("PARENT - shm_open(create):");
>+		} else {
>+			if ((ftruncate(fd, sizeof(test_data))) == -1)
>+			{
>+				printf("%-40s: %s", "ftruncate", strerror(errno));
>+				shm_unlink(shared_name);
>+				return 0;
>+			}
>+
>+			ptest_data = mmap(0, sizeof(test_data), PROT_READ + PROT_WRITE, MAP_SHARED, fd, 0);
>+			if (ptest_data == MAP_FAILED)
>+			{
>+				perror("PARENT - mmap:");
>+				if (shm_unlink(shared_name) == -1) {
>+					perror("PARENT - shm_unlink:");
>+				}
>+				return 0;
>+			}
>+			for (i=0; i <sizeof(test_data); i++)
>+				ptest_data[i] = test_data[i];
>+
>+			// signal child
>+			write(pfds[1], "rdy", 5);
>+			// wait for child
>+			wait(&rv);
>+
>+			// Cleanup
>+			munmap(ptest_data, sizeof(test_data));
>+			if (shm_unlink(shared_name) == -1) {
>+				perror("PARENT - shm_unlink:");
>+			}
>+		}
>+	}
>+	return 0;
>+}
>-- 
>1.5.4.3
>



More information about the uClibc mailing list