From 4b7e3cff8147c8c149d82c0a4dcf16183ec26f93 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Mon, 30 May 2005 10:13:54 +0000 Subject: [PATCH] added ipc_gid for direct plugins --- src/pcm/pcm_direct.c | 15 +++++++++++++++ src/pcm/pcm_direct.h | 1 + src/pcm/pcm_dmix.c | 43 +++++++++++++++++++++++++++++++++++++++---- src/pcm/pcm_dshare.c | 28 ++++++++++++++++++++++++++-- src/pcm/pcm_dsnoop.c | 28 ++++++++++++++++++++++++++-- 5 files changed, 107 insertions(+), 8 deletions(-) diff --git a/src/pcm/pcm_direct.c b/src/pcm/pcm_direct.c index af1196a1..3610a95f 100644 --- a/src/pcm/pcm_direct.c +++ b/src/pcm/pcm_direct.c @@ -50,10 +50,21 @@ 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; diff --git a/src/pcm/pcm_direct.h b/src/pcm/pcm_direct.h index 4ccb499e..5b6b938b 100644 --- a/src/pcm/pcm_direct.h +++ b/src/pcm/pcm_direct.h @@ -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 */ diff --git a/src/pcm/pcm_dmix.c b/src/pcm/pcm_dmix.c index d3bf3376..24aecdeb 100644 --- a/src/pcm/pcm_dmix.c +++ b/src/pcm/pcm_dmix.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -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, ¶ms, bindings, slowptr, root, sconf, stream, mode); + err = snd_pcm_dmix_open(pcmp, name, ipc_key, ipc_perm, ipc_gid, ¶ms, bindings, slowptr, root, sconf, stream, mode); if (err < 0) snd_config_delete(sconf); return err; diff --git a/src/pcm/pcm_dshare.c b/src/pcm/pcm_dshare.c index 23de0693..434428f4 100644 --- a/src/pcm/pcm_dshare.c +++ b/src/pcm/pcm_dshare.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -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, ¶ms, bindings, slowptr, root, sconf, stream, mode); + err = snd_pcm_dshare_open(pcmp, name, ipc_key, ipc_perm, ipc_gid, ¶ms, bindings, slowptr, root, sconf, stream, mode); if (err < 0) snd_config_delete(sconf); return err; diff --git a/src/pcm/pcm_dsnoop.c b/src/pcm/pcm_dsnoop.c index 34dfb9e8..82b55087 100644 --- a/src/pcm/pcm_dsnoop.c +++ b/src/pcm/pcm_dsnoop.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -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, ¶ms, bindings, slowptr, root, sconf, stream, mode); + err = snd_pcm_dsnoop_open(pcmp, name, ipc_key, ipc_perm, ipc_gid, ¶ms, bindings, slowptr, root, sconf, stream, mode); if (err < 0) snd_config_delete(sconf); return err; -- 2.47.1