Actually, there's a much simpler version of this patch, since the
previous code provided some extra validation and pretty error
messages, but no information that couldn't be provided by
snd_ctl_open(), e.g.:
....
gnulem-336-~> envy24control -Dfoo
ALSA lib control.c:902:(snd_ctl_open_noupdate) Invalid CTL foo
snd_ctl_open: No such file or directory
....
diff --git a/envy24control/envy24control.c b/envy24control/envy24control.c
index 0b2749e..3798ba3 100644
--- a/envy24control/envy24control.c
+++ b/envy24control/envy24control.c
@@ -2084,24 +2166,50 @@ int main(int argc, char **argv)
view_spdif_playback = 0;
profiles_file_name = DEFAULT_PROFILERC;
default_profile = NULL;
while ((c = getopt_long(argc, argv, "D:c:f:i:m:Mo:p:s:w:vt:",
long_options, NULL)) != -1) {
switch (c) {
case 'D':
- name = optarg;
- card_number = atoi(strchr(name, ':') + sizeof(char));
- if (card_number < 0 || card_number >= MAX_CARD_NUMBERS) {
- fprintf(stderr, "envy24control: invalid card number %d\n", card_number);
- exit(1);
- }
+ /*
+ * NPM: use ALSA code to fix/validate
+ *
https://bugzilla.redhat.com/show_bug.cgi?id=602900
+ * The old code assumed ':' present, e.g. "-Dhw:66", (w/
+ * .asoundrc "ctl.66 {type hw, card M66}") and would
+ * coredump if given "-D66". Here, by not worrying about
+ * "hw:" and passing "optarg" as-is via 'name' to
+ * snd_ctl_open() below, resolves the issue, giving similar
+ * behavior as 'amixer'. However, letting snd_ctl_open()
+ * validate gives less helpful error messages on
+ * failure: "envy24control -Dhw:foo"
+ * ==> "snd_ctl_open: No such device"
+ * So validate the arg as ALSA CTL, providing
+ * a more specific error message and fail first if not valid.
+ */
+ name = optarg; /* NPM: e.g. pass "-D66" unaltered to
snd_ctl_open() and let it validate valid ALSA CTL name */
+ if (index(optarg, ':')) { /* NPM: handle e.g. optarg == "hw:M66" */
+ card_number = snd_card_get_index(strchr(optarg, ':') + sizeof(char));
+ if (card_number < 0) {
+ fprintf(stderr, "envy24control: invalid ALSA audio device,
invalid index or name for card: %s\n", optarg);
+ exit(1);
+ }
+ }
break;
case 'c':
- i = atoi(optarg);
- if (i < 0 || i >= MAX_CARD_NUMBERS) {
- fprintf(stderr, "envy24control: invalid card number %d\n", i);
+ /*
+ NPM: use snd_card_get_index() to fix/validate
+
https://bugzilla.redhat.com/show_bug.cgi?id=602900
+ * NPM: nb :"The accepted format is
+ * an integer value in ASCII representation or the card
+ * identifier (the id parameter for sound-card
+ * drivers). The control device name like
+ * /dev/snd/controlC0 is accepted, too."
+ */
+ card_number = snd_card_get_index(optarg);
+ if (card_number < 0) { /* NPM: code orig from alsa-utils/alsamixer/cli.c */
+ fprintf(stderr, "envy24control: invalid ALSA index or name for
audio card: %s\n", optarg);
exit(1);
}
- card_number = i;
- sprintf(tmpname, "hw:%d", i);
+ sprintf(tmpname, "hw:%d", card_number); /* e.g. "hw:M66" for arg
"-cM66" passed to snd_ctl_open() below */
name = tmpname;
break;
case 'f':
...................................
Niels
http://nielsmayer.com