Hi Guys,

Was doing some work with Sys V Semaphores in PHP today. Noticed a few
problems. Patch to add sem_remove() (ie, remove semaphore referenced by
Indetifier) is attached (C and header).

Previously, there was no other way to destroy semaphores opened in PHP. I
was using ipcrm too much and just wrote the code.

Happy to take over the maintenance of this section since I will be using
it a lot for some applications I am writing.

In doing this, I found a bug in Sys V Shm. Patch for this attached.

I've done this in something of a hurry so have not been able to make sure
that I am releasing the resources from the Zend API correctly. Will get
around to that, based on feedback (if any?).

All patches have been generated with diff -u.


Thanks

Gavin Sherry
Alcove Systems Engineering.
--- ext/sysvsem/sysvsem.c.orig  Thu Mar 15 22:40:18 2001
+++ ext/sysvsem/sysvsem.c       Fri Mar 16 00:52:18 2001
@@ -53,6 +53,7 @@
        PHP_FE(sem_get,                 NULL)
        PHP_FE(sem_acquire,             NULL)
        PHP_FE(sem_release,             NULL)
+       PHP_FE(sem_remove,              NULL)
        {NULL, NULL, NULL}
 };
 
@@ -92,6 +93,14 @@
        sysvsem_sem *sem_ptr = (sysvsem_sem *)rsrc->ptr;
        struct sembuf sop[2];
 
+/*
+ * if count == -1, semaphore has been removed
+ * Need better way to handle this
+ */
+
+       if(sem_ptr->count == -1) {
+               return;
+       }
        /* Decrement the usage count. */
 
        sop[0].sem_num = SYSVSEM_USAGE;
@@ -343,6 +352,78 @@
 {
        php_sysvsem_semop(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
 }
+/* }}} */
+
+
+
+
+/* {{{ proto int sem_remove(int id)
+   Removes semaphore from Unix systems */
+
+/*
+ * contributed by Gavin Sherry [EMAIL PROTECTED]
+ * Fri Mar 16 00:50:13 EST 2001
+ */
+
+PHP_FUNCTION(sem_remove)
+{
+        pval **arg_id;
+        int id,type;
+       sysvsem_sem *sem_ptr;
+#if HAVE_SEMUN
+       union semun un;
+#endif
+
+
+
+/*
+ * bug in the original SHM code. First arg is id, not key. Fix this!
+ */
+/*
+        if(ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg_key) == FAILURE) {
+                WRONG_PARAM_COUNT;
+        }
+*/
+
+        if(ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg_id) == FAILURE) {
+                WRONG_PARAM_COUNT;
+        }
+
+
+        convert_to_long_ex(arg_id);
+
+        id = (*arg_id)->value.lval;
+
+        sem_ptr = (sysvsem_sem *) zend_list_find(id, &type);
+
+        if (type!=php_sysvsem_module.le_sem) {
+                php_error(E_WARNING, "%d is not a SysV semaphore index", id);
+                RETURN_FALSE;
+        }
+
+
+#if HAVE_SEMUN
+        if(semctl(sem_ptr->semid,NULL,IPC_STAT,un)<0) {
+#else
+       if(semctl(sem_ptr->semid,NULL,IPC_STAT,NULL)<0) {
+#endif
+                php_error(E_WARNING, "%d is not a existing SysV Semaphore Id", id);
+                RETURN_FALSE;
+        }
+
+       if(semctl(sem_ptr->semid,NULL,IPC_RMID,NULL)<0) {
+                php_error(E_WARNING, "sem_remove() failed for id %d: %s", id, 
+strerror(errno));
+                RETURN_FALSE;
+        }
+       
+       /* let release_sysvsem_sem knows we have removed
+        * the semaphore to avoid issues with releasing.
+        */ 
+
+       sem_ptr->count = -1;
+        RETURN_TRUE;
+}
+
 /* }}} */
 
 #endif /* HAVE_SYSVSEM */
--- ext/sysvsem/php_sysvsem.h.orig      Fri Mar 16 01:44:26 2001
+++ ext/sysvsem/php_sysvsem.h   Fri Mar 16 01:44:17 2001
@@ -30,6 +30,7 @@
 PHP_FUNCTION(sem_get);
 PHP_FUNCTION(sem_acquire);
 PHP_FUNCTION(sem_release);
+PHP_FUNCTION(sem_remove);
 
 typedef struct {
        int le_sem;
--- ext/sysvshm/sysvshm.c.orig  Fri Mar 16 01:22:16 2001
+++ ext/sysvshm/sysvshm.c       Fri Mar 16 01:42:15 2001
@@ -173,26 +173,40 @@
 /* }}} */
 /* {{{ proto int shm_remove(int shm_identifier)
    Removes shared memory from Unix systems */
+
+/* patched to use the correct argument Fri Mar 16 01:22:50 EST 2001
+ * Gavin Sherry [EMAIL PROTECTED]
+ */
+
 PHP_FUNCTION(shm_remove)
 {
-       pval **arg_key;
+       pval **arg_id;
        long id;
-       key_t key;
+       int type;
+       sysvshm_shm *shm_list_ptr;
 
-       if(ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg_key) == FAILURE) {
+       if(ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg_id) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
 
-       convert_to_long_ex(arg_key);
+       convert_to_long_ex(arg_id);
        
-       key = (*arg_key)->value.lval;
+       id = (*arg_id)->value.lval;
 
+/*
+ * this isn't what we're looking to do 
+ */
+
+/*
        if((id=shmget(key,0,0))<0) {
                php_error(E_WARNING, "%d is not a existing SysV shared memory key", 
key);
                RETURN_FALSE;
        }
-       if(shmctl(id,IPC_RMID,NULL)<0) {
-               php_error(E_WARNING, "shm_remove() failed for key 0x%x: %s", key, 
strerror(errno));
+*/
+
+       shm_list_ptr = (sysvshm_shm *) zend_list_find(id, &type);
+       if(shmctl(shm_list_ptr->id,IPC_RMID,NULL)<0) {
+               php_error(E_WARNING, "shm_remove() failed for key 0x%x, id %i: %s", 
+shm_list_ptr->key, id,strerror(errno));
                RETURN_FALSE;
        } 
 
-- 
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
To contact the list administrators, e-mail: [EMAIL PROTECTED]

Reply via email to