]> git.alsa-project.org Git - alsa-lib.git/commitdiff
added ipc_gid for direct plugins
authorJaroslav Kysela <perex@perex.cz>
Mon, 30 May 2005 10:13:54 +0000 (10:13 +0000)
committerJaroslav Kysela <perex@perex.cz>
Mon, 30 May 2005 10:13:54 +0000 (10:13 +0000)
src/pcm/pcm_direct.c
src/pcm/pcm_direct.h
src/pcm/pcm_dmix.c
src/pcm/pcm_dshare.c
src/pcm/pcm_dsnoop.c

index af1196a17bce44d6ac2f0fc3446c741212a99e82..3610a95fc3c540d73f95a85ab945e1979255c8ce 100644 (file)
 
 int snd_pcm_direct_semaphore_create_or_connect(snd_pcm_direct_t *dmix)
 {
+       struct shmid_ds buf;
+
        dmix->semid = semget(dmix->ipc_key, DIRECT_IPC_SEMS,
                             IPC_CREAT | dmix->ipc_perm);
        if (dmix->semid < 0)
                return -errno;
+       if (dmix->ipc_gid < 0)
+               return 0;
+       if (shmctl(dmix->semid, IPC_STAT, &buf) < 0) {
+               int err = -errno;
+               snd_pcm_direct_semaphore_discard(dmix);
+               return err;
+       }
+       buf.shm_perm.gid = dmix->ipc_gid;
+       shmctl(dmix->semid, IPC_SET, &buf);
        return 0;
 }
 
@@ -120,6 +131,10 @@ retryget:
        }
        if (buf.shm_nattch == 1) {      /* we're the first user, clear the segment */
                memset(dmix->shmptr, 0, sizeof(snd_pcm_direct_share_t));
+               if (dmix->ipc_gid >= 0) {
+                       buf.shm_perm.gid = dmix->ipc_gid;
+                       shmctl(dmix->shmid, IPC_SET, &buf);
+               }
                return 1;
        }
        return 0;
index 4ccb499e1016f2918da546be0d0f56abc0e801c4..5b6b938ba7cfb4bfe7adb08516ddf4768a8e0c3e 100644 (file)
@@ -74,6 +74,7 @@ struct snd_pcm_direct {
        snd_pcm_type_t type;            /* type (dmix, dsnoop, dshare) */
        key_t ipc_key;                  /* IPC key for semaphore and memory */
        mode_t ipc_perm;                /* IPC socket permissions */
+       int ipc_gid;                    /* IPC socket gid */
        int semid;                      /* IPC global semaphore identification */
        int shmid;                      /* IPC global shared memory identification */
        snd_pcm_direct_share_t *shmptr; /* pointer to shared memory area */
index d3bf3376ff925482984b68b450accee6ce466232..24aecdeb7d313702e74cfde71de35c1f22ddb444 100644 (file)
@@ -34,6 +34,7 @@
 #include <string.h>
 #include <fcntl.h>
 #include <ctype.h>
+#include <grp.h>
 #include <sys/ioctl.h>
 #include <sys/mman.h>
 #include <sys/shm.h>
@@ -76,7 +77,7 @@ retryshm:
        dmix->u.dmix.shmid_sum = shmget(dmix->ipc_key + 1, size,
                                        IPC_CREAT | dmix->ipc_perm);
        err = -errno;
-       if (dmix->u.dmix.shmid_sum < 0){
+       if (dmix->u.dmix.shmid_sum < 0) {
                if (errno == EINVAL)
                if ((tmpid = shmget(dmix->ipc_key + 1, 0, dmix->ipc_perm)) != -1)
                if (!shmctl(tmpid, IPC_STAT, &buf))
@@ -86,10 +87,20 @@ retryshm:
                    goto retryshm;
                return err;
        }
+       if (!shmctl(dmix->u.dmix.shmid_sum, IPC_STAT, &buf)) {
+               err = -errno;
+               shm_sum_discard(dmix);
+               return err;
+       }
+       if (dmix->ipc_gid >= 0) {
+               buf.shm_perm.gid = dmix->ipc_gid;
+               shmctl(dmix->u.dmix.shmid_sum, IPC_SET, &buf); 
+       }
        dmix->u.dmix.sum_buffer = shmat(dmix->u.dmix.shmid_sum, 0, 0);
        if (dmix->u.dmix.sum_buffer == (void *) -1) {
+               err = -errno;
                shm_sum_discard(dmix);
-               return -errno;
+               return err;
        }
        mlock(dmix->u.dmix.sum_buffer, size);
        return 0;
@@ -715,6 +726,7 @@ static snd_pcm_fast_ops_t snd_pcm_dmix_fast_ops = {
  * \param name Name of PCM
  * \param ipc_key IPC key for semaphore and shared memory
  * \param ipc_perm IPC permissions for semaphore and shared memory
+ * \param ipc_gid IPC group ID for semaphore and shared memory
  * \param params Parameters for slave
  * \param bindings Channel bindings
  * \param slowptr Slow but more precise pointer updates
@@ -728,7 +740,7 @@ static snd_pcm_fast_ops_t snd_pcm_dmix_fast_ops = {
  *          changed in future.
  */
 int snd_pcm_dmix_open(snd_pcm_t **pcmp, const char *name,
-                     key_t ipc_key, mode_t ipc_perm,
+                     key_t ipc_key, mode_t ipc_perm, int ipc_gid,
                      struct slave_params *params,
                      snd_config_t *bindings,
                      int slowptr,
@@ -759,6 +771,7 @@ int snd_pcm_dmix_open(snd_pcm_t **pcmp, const char *name,
        
        dmix->ipc_key = ipc_key;
        dmix->ipc_perm = ipc_perm;
+       dmix->ipc_gid = ipc_gid;
        dmix->semid = -1;
        dmix->shmid = -1;
 
@@ -1050,6 +1063,7 @@ int _snd_pcm_dmix_open(snd_pcm_t **pcmp, const char *name,
        int bsize, psize, ipc_key_add_uid = 0, slowptr = 0;
        key_t ipc_key = 0;
        mode_t ipc_perm = 0600;
+       int ipc_gid = -1;
        int err;
        snd_config_for_each(i, next, conf) {
                snd_config_t *n = snd_config_iterator_entry(i);
@@ -1063,6 +1077,7 @@ int _snd_pcm_dmix_open(snd_pcm_t **pcmp, const char *name,
                        err = snd_config_get_integer(n, &key);
                        if (err < 0) {
                                SNDERR("The field ipc_key must be an integer type");
+
                                return err;
                        }
                        ipc_key = key;
@@ -1083,6 +1098,26 @@ int _snd_pcm_dmix_open(snd_pcm_t **pcmp, const char *name,
                        ipc_perm = strtol(perm, &endp, 8);
                        continue;
                }
+               if (strcmp(id, "ipc_gid") == 0) {
+                       char *group;
+                       char *endp;
+                       err = snd_config_get_ascii(n, &group);
+                       if (err < 0) {
+                               SNDERR("The field ipc_gid must be a valid group");
+                               return err;
+                       }
+                       if (isdigit(*group) == 0) {
+                               struct group *grp = getgrnam(group);
+                               if (grp == NULL) {
+                                       SNDERR("The field ipc_gid must be a valid group (create group %s)", group);
+                                       return -EINVAL;
+                               }
+                               ipc_gid = grp->gr_gid;
+                       } else {
+                               ipc_perm = strtol(group, &endp, 10);
+                       }
+                       continue;
+               }
                if (strcmp(id, "ipc_key_add_uid") == 0) {
                        if ((err = snd_config_get_bool(n)) < 0) {
                                SNDERR("The field ipc_key_add_uid must be a boolean type");
@@ -1155,7 +1190,7 @@ int _snd_pcm_dmix_open(snd_pcm_t **pcmp, const char *name,
        params.period_size = psize;
        params.buffer_size = bsize;
 
-       err = snd_pcm_dmix_open(pcmp, name, ipc_key, ipc_perm, &params, bindings, slowptr, root, sconf, stream, mode);
+       err = snd_pcm_dmix_open(pcmp, name, ipc_key, ipc_perm, ipc_gid, &params, bindings, slowptr, root, sconf, stream, mode);
        if (err < 0)
                snd_config_delete(sconf);
        return err;
index 23de0693535515b5f839ac879d568f072ee5bc17..434428f470dcff7779a1de1a4d93e65b704d943a 100644 (file)
@@ -34,6 +34,7 @@
 #include <string.h>
 #include <fcntl.h>
 #include <ctype.h>
+#include <grp.h>
 #include <sys/ioctl.h>
 #include <sys/mman.h>
 #include <sys/shm.h>
@@ -578,6 +579,7 @@ static snd_pcm_fast_ops_t snd_pcm_dshare_fast_ops = {
  * \param name Name of PCM
  * \param ipc_key IPC key for semaphore and shared memory
  * \param ipc_perm IPC permissions for semaphore and shared memory
+ * \param ipc_gid IPC group ID for semaphore and shared memory
  * \param params Parameters for slave
  * \param bindings Channel bindings
  * \param slowptr Slow but more precise pointer updates
@@ -591,7 +593,7 @@ static snd_pcm_fast_ops_t snd_pcm_dshare_fast_ops = {
  *          changed in future.
  */
 int snd_pcm_dshare_open(snd_pcm_t **pcmp, const char *name,
-                       key_t ipc_key, mode_t ipc_perm,
+                       key_t ipc_key, mode_t ipc_perm, int ipc_gid,
                        struct slave_params *params,
                        snd_config_t *bindings,
                        int slowptr,
@@ -629,6 +631,7 @@ int snd_pcm_dshare_open(snd_pcm_t **pcmp, const char *name,
        
        dshare->ipc_key = ipc_key;
        dshare->ipc_perm = ipc_perm;
+       dshare->ipc_gid = ipc_gid;
        dshare->semid = -1;
        dshare->shmid = -1;
 
@@ -851,6 +854,7 @@ int _snd_pcm_dshare_open(snd_pcm_t **pcmp, const char *name,
        int bsize, psize, ipc_key_add_uid = 0, slowptr = 0;
        key_t ipc_key = 0;
        mode_t ipc_perm = 0600;
+       int ipc_gid = -1;
        
        int err;
        snd_config_for_each(i, next, conf) {
@@ -885,6 +889,26 @@ int _snd_pcm_dshare_open(snd_pcm_t **pcmp, const char *name,
                        ipc_perm = strtol(perm, &endp, 8);
                        continue;
                }
+               if (strcmp(id, "ipc_gid") == 0) {
+                       char *group;
+                       char *endp;
+                       err = snd_config_get_ascii(n, &group);
+                       if (err < 0) {
+                               SNDERR("The field ipc_gid must be a valid group");
+                               return err;
+                       }
+                       if (isdigit(*group) == 0) {
+                               struct group *grp = getgrnam(group);
+                               if (group == NULL) {
+                                       SNDERR("The field ipc_gid must be a valid group (create group %s)", grp);
+                                       return -EINVAL;
+                               }
+                               ipc_gid = grp->gr_gid;
+                       } else {
+                               ipc_perm = strtol(group, &endp, 10);
+                       }
+                       continue;
+               }
                if (strcmp(id, "ipc_key_add_uid") == 0) {
                        err = snd_config_get_bool(n);
                        if (err < 0) {
@@ -950,7 +974,7 @@ int _snd_pcm_dshare_open(snd_pcm_t **pcmp, const char *name,
 
        params.period_size = psize;
        params.buffer_size = bsize;
-       err = snd_pcm_dshare_open(pcmp, name, ipc_key, ipc_perm, &params, bindings, slowptr, root, sconf, stream, mode);
+       err = snd_pcm_dshare_open(pcmp, name, ipc_key, ipc_perm, ipc_gid, &params, bindings, slowptr, root, sconf, stream, mode);
        if (err < 0)
                snd_config_delete(sconf);
        return err;
index 34dfb9e8c51aea1544a67414cdc41612f526a204..82b55087d03a3913ebe6e8c1d55983e75fa03a77 100644 (file)
@@ -34,6 +34,7 @@
 #include <string.h>
 #include <fcntl.h>
 #include <ctype.h>
+#include <grp.h>
 #include <sys/ioctl.h>
 #include <sys/mman.h>
 #include <sys/shm.h>
@@ -477,6 +478,7 @@ static snd_pcm_fast_ops_t snd_pcm_dsnoop_fast_ops = {
  * \param name Name of PCM
  * \param ipc_key IPC key for semaphore and shared memory
  * \param ipc_perm IPC permissions for semaphore and shared memory
+ * \param ipc_gid IPC group ID for semaphore and shared memory
  * \param params Parameters for slave
  * \param bindings Channel bindings
  * \param slowptr Slow but more precise pointer updates
@@ -490,7 +492,7 @@ static snd_pcm_fast_ops_t snd_pcm_dsnoop_fast_ops = {
  *          changed in future.
  */
 int snd_pcm_dsnoop_open(snd_pcm_t **pcmp, const char *name,
-                       key_t ipc_key, mode_t ipc_perm,
+                       key_t ipc_key, mode_t ipc_perm, int ipc_gid,
                        struct slave_params *params,
                        snd_config_t *bindings,
                        int slowptr,
@@ -520,6 +522,7 @@ int snd_pcm_dsnoop_open(snd_pcm_t **pcmp, const char *name,
        
        dsnoop->ipc_key = ipc_key;
        dsnoop->ipc_perm = ipc_perm;
+       dsnoop->ipc_gid = ipc_gid;
        dsnoop->semid = -1;
        dsnoop->shmid = -1;
 
@@ -732,6 +735,7 @@ int _snd_pcm_dsnoop_open(snd_pcm_t **pcmp, const char *name,
        int bsize, psize, ipc_key_add_uid = 0, slowptr = 0;
        key_t ipc_key = 0;
        mode_t ipc_perm = 0600;
+       int ipc_gid = -1;
        int err;
 
        snd_config_for_each(i, next, conf) {
@@ -766,6 +770,26 @@ int _snd_pcm_dsnoop_open(snd_pcm_t **pcmp, const char *name,
                        ipc_perm = strtol(perm, &endp, 8);
                        continue;
                }
+               if (strcmp(id, "ipc_gid") == 0) {
+                       char *group;
+                       char *endp;
+                       err = snd_config_get_ascii(n, &group);
+                       if (err < 0) {
+                               SNDERR("The field ipc_gid must be a valid group");
+                               return err;
+                       }
+                       if (isdigit(*group) == 0) {
+                               struct group *grp = getgrnam(group);
+                               if (group == NULL) {
+                                       SNDERR("The field ipc_gid must be a valid group (create group %s)", grp);
+                                       return -EINVAL;
+                               }
+                               ipc_gid = grp->gr_gid;
+                       } else {
+                               ipc_perm = strtol(group, &endp, 10);
+                       }
+                       continue;
+               }
                if (strcmp(id, "ipc_key_add_uid") == 0) {
                        err = snd_config_get_bool(n);
                        if (err < 0) {
@@ -831,7 +855,7 @@ int _snd_pcm_dsnoop_open(snd_pcm_t **pcmp, const char *name,
 
        params.period_size = psize;
        params.buffer_size = bsize;
-       err = snd_pcm_dsnoop_open(pcmp, name, ipc_key, ipc_perm, &params, bindings, slowptr, root, sconf, stream, mode);
+       err = snd_pcm_dsnoop_open(pcmp, name, ipc_key, ipc_perm, ipc_gid, &params, bindings, slowptr, root, sconf, stream, mode);
        if (err < 0)
                snd_config_delete(sconf);
        return err;