Bad system call (core dumped)
Joseph Koshy
joseph.koshy at gmail.com
Sun Feb 19 10:09:42 PST 2006
jk> Userland code should be checking for kernel support for
jk> features before attempting to use them.
dx> I don't think user code should check it before it can be
dx> used, actually, it is being used by thread libraries to
dx> implement named semaphore, it is requred by POSIX.
Well, support for posix semaphores is not turned on in
GENERIC, and so code that calls sem_init(3)
is rudely sent a SIGSYS today.
How about the attached patch to make our libraries better
behaved with kernels that lack the P1003_1B_SEMAPHORES
option?
--
FreeBSD Volunteer, http://people.freebsd.org/~jkoshy
-------------- next part --------------
Index: libc/gen/sem.c
===================================================================
RCS file: /cvs/FreeBSD/src/lib/libc/gen/sem.c,v
retrieving revision 1.15
diff -u -u -r1.15 sem.c
--- libc/gen/sem.c 18 Oct 2005 17:24:03 -0000 1.15
+++ libc/gen/sem.c 19 Feb 2006 17:48:17 -0000
@@ -59,6 +59,7 @@
#include "namespace.h"
#include <sys/types.h>
#include <sys/queue.h>
+#include <sys/sysctl.h>
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
@@ -70,6 +71,7 @@
#include "un-namespace.h"
#include "libc_private.h"
+static int sem_supported = -1; /* changed by the first call to __sem_init() */
static sem_t sem_alloc(unsigned int value, semid_t semid, int system_sem);
static void sem_free(sem_t sem);
@@ -140,6 +142,21 @@
__sem_init(sem_t *sem, int pshared, unsigned int value)
{
semid_t semid;
+ int mib[2];
+ size_t len;
+
+ if (sem_supported < 0) {
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_SEMAPHORES;
+ len = sizeof(sem_supported);
+ if (sysctl(mib, 2, &sem_supported, &len, NULL, 0) < 0)
+ sem_supported = 0;
+ }
+
+ if (!sem_supported) {
+ errno = ENOSYS;
+ return -1;
+ }
/*
* We always have to create the kernel semaphore if the
Index: libc/gen/sem_init.3
===================================================================
RCS file: /cvs/FreeBSD/src/lib/libc/gen/sem_init.3,v
retrieving revision 1.18
diff -u -u -r1.18 sem_init.3
--- libc/gen/sem_init.3 13 Jul 2005 13:15:21 -0000 1.18
+++ libc/gen/sem_init.3 19 Feb 2006 18:02:56 -0000
@@ -78,6 +78,10 @@
.Dv SEM_VALUE_MAX .
.It Bq Er ENOSPC
Memory allocation error.
+.It Bq Er ENOSYS
+The system does not support
+.Tn POSIX
+semaphores.
.It Bq Er EPERM
Unable to initialize a shared semaphore.
.El
@@ -94,6 +98,12 @@
function conforms to
.St -p1003.1-96 .
.Pp
+Support for
+.Tn POSIX
+semaphores requires the currently running kernel to have been configured
+with
+.Cd "options P1003_1B_SEMAPHORES" .
+.Pp
This implementation does not support shared semaphores, and reports this fact
by setting
.Va errno
Index: libthr/thread/thr_sem.c
===================================================================
RCS file: /cvs/FreeBSD/src/lib/libthr/thread/thr_sem.c,v
retrieving revision 1.6
diff -u -u -r1.6 thr_sem.c
--- libthr/thread/thr_sem.c 1 Sep 2005 15:21:23 -0000 1.6
+++ libthr/thread/thr_sem.c 19 Feb 2006 17:34:56 -0000
@@ -32,6 +32,7 @@
#include "namespace.h"
#include <sys/types.h>
+#include <sys/sysctl.h>
#include <sys/queue.h>
#include <errno.h>
#include <fcntl.h>
@@ -44,6 +45,7 @@
#include "thr_private.h"
+static int sem_supported = -1; /* changed by the first call to _sem_init() */
__weak_reference(_sem_init, sem_init);
__weak_reference(_sem_destroy, sem_destroy);
@@ -99,6 +101,21 @@
_sem_init(sem_t *sem, int pshared, unsigned int value)
{
semid_t semid;
+ int mib[2];
+ size_t len;
+
+ if (sem_supported < 0) {
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_SEMAPHORES;
+ len = sizeof(sem_supported);
+ if (sysctl(mib, 2, &sem_supported, &len, NULL, 0) < 0)
+ sem_supported = 0;
+ }
+
+ if (!sem_supported) {
+ errno = ENOSYS;
+ return -1;
+ }
semid = (semid_t)SEM_USER;
if ((pshared != 0) && (ksem_init(&semid, value) != 0))
Index: libpthread/thread/thr_sem.c
===================================================================
RCS file: /cvs/FreeBSD/src/lib/libpthread/thread/thr_sem.c,v
retrieving revision 1.17
diff -u -u -r1.17 thr_sem.c
--- libpthread/thread/thr_sem.c 1 Sep 2005 15:16:46 -0000 1.17
+++ libpthread/thread/thr_sem.c 19 Feb 2006 17:44:36 -0000
@@ -31,6 +31,7 @@
#include "namespace.h"
#include <sys/types.h>
+#include <sys/sysctl.h>
#include <sys/queue.h>
#include <errno.h>
#include <fcntl.h>
@@ -43,7 +44,6 @@
#include "libc_private.h"
#include "thr_private.h"
-
extern int pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *);
extern int pthread_cond_timedwait(pthread_cond_t *, pthread_mutex_t *,
struct timespec *);
@@ -53,6 +53,7 @@
__weak_reference(_sem_timedwait, sem_timedwait);
__weak_reference(_sem_post, sem_post);
+static int sem_supported = -1; /* changed by the first call to _sem_init() */
static inline int
sem_check_validity(sem_t *sem)
@@ -123,6 +124,21 @@
_sem_init(sem_t *sem, int pshared, unsigned int value)
{
semid_t semid;
+ int mib[2];
+ size_t len;
+
+ if (sem_supported < 0) {
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_SEMAPHORES;
+ len = sizeof(sem_supported);
+ if (sysctl(mib, 2, &sem_supported, &len, NULL, 0) < 0)
+ sem_supported = 0;
+ }
+
+ if (!sem_supported) {
+ errno = ENOSYS;
+ return -1;
+ }
semid = (semid_t)SEM_USER;
if ((pshared != 0) && (ksem_init(&semid, value) != 0))
More information about the freebsd-current
mailing list