]> git.alsa-project.org Git - alsa-utils.git/commitdiff
Add -x option for removing all exported connections
authorTakashi Iwai <tiwai@suse.de>
Thu, 31 Aug 2000 11:20:34 +0000 (11:20 +0000)
committerTakashi Iwai <tiwai@suse.de>
Thu, 31 Aug 2000 11:20:34 +0000 (11:20 +0000)
seq/aconnect/aconnect.1
seq/aconnect/aconnect.c

index b47b4c2bcb962b3fee42db9fcc7e12477684d80a..4d7592424634729169602fede71d48108c885969 100644 (file)
@@ -1,4 +1,4 @@
-.TH aconnect 1 "January 1, 2000"
+.TH aconnect 1 "August 31, 2000"
 .LO 1
 .SH NAME
 aconnect \- ALSA sequencer connection manager
@@ -9,6 +9,9 @@ aconnect \- ALSA sequencer connection manager
 .br
 .B aconnect
 \-i|-o [-options]
+.br
+.B aconnect
+\-x
 
 .SH DESCRIPTION
 .B aconnect
@@ -59,6 +62,12 @@ client 64: '0: MIDI Synth' [group=] [type=kernel]
 Similary, to see the output ports, use
 .B \-o
 flag.
+.PP
+You can remove all existing exported connections using
+.B \-x
+option.  This function is useful for terminating the ALSA drivers,
+because the modules with sequencer connections cannot be unloaded
+unless their connections are removed.
 
 .SH OPTIONS
 .SS CONNNECTION MANAGEMENT
@@ -120,8 +129,13 @@ and
 mean the connection includes real-time and tick conversion on the listed
 queue, respectively.
 
+.SS REMOVE ALL CONNECTIONS
+.TP
+.B \-x, --removeall
+Remove all exported connections.
+
 .SH "SEE ALSO"
 aseqnet(1), aseqview(1)
 
 .SH AUTHOR
-Takashi Iwai <iwai@ww.uni-erlangen.de>.
+Takashi Iwai <tiwai@suse.de>
index 935e88ca3e92bfde564368db6a70338b99c5124d..f380256b548782e56cde873db70cd4b1e2098c96 100644 (file)
@@ -44,6 +44,8 @@ static void usage(void)
        fprintf(stderr, "     -o,--output         list output (writable) ports\n");
        fprintf(stderr, "     -g,--group name     specify the group name\n");
        fprintf(stderr, "     -l,--list           list current connections of each port\n");
+       fprintf(stderr, " * Remove all exported connections\n");
+       fprintf(stderr, "     -x, --removeall\n");
 }
 
 /*
@@ -116,13 +118,15 @@ static void list_subscribers(snd_seq_t *seq, int client, int port)
 }
 
 /*
- * list all ports
+ * search all ports
  */
-static void list_ports(snd_seq_t *seq, char *group, int perm, int list_subs)
+typedef void (*action_func_t)(snd_seq_t *seq, snd_seq_client_info_t *cinfo, snd_seq_port_info_t *pinfo, int count);
+
+static void do_search_port(snd_seq_t *seq, char *group, int perm, action_func_t do_action)
 {
        snd_seq_client_info_t cinfo;
        snd_seq_port_info_t pinfo;
-       int client_printed;
+       int count;
 
        cinfo.client = -1;
        cinfo.name[0] = 0;
@@ -133,18 +137,11 @@ static void list_ports(snd_seq_t *seq, char *group, int perm, int list_subs)
                pinfo.port = -1;
                pinfo.name[0] = 0;
                strncpy(pinfo.group, group, sizeof(pinfo.group));
-               client_printed = 0;
+               count = 0;
                while (snd_seq_query_next_port(seq, &pinfo) >= 0) {
                        if (check_permission(&pinfo, group, perm)) {
-                               if (! client_printed) {
-                                       printf("client %d: '%s' [group=%s] [type=%s]\n",
-                                              cinfo.client, cinfo.name, cinfo.group,
-                                              (cinfo.type == USER_CLIENT ? "user" : "kernel"));
-                                       client_printed = 1;
-                               }
-                               printf("  %3d '%-16s' [group=%s]\n", pinfo.port, pinfo.name, pinfo.group);
-                               if (list_subs)
-                                       list_subscribers(seq, pinfo.client, pinfo.port);
+                               do_action(seq, &cinfo, &pinfo, count);
+                               count++;
                        }
                        /* reset query names */
                        pinfo.name[0] = 0;
@@ -157,8 +154,101 @@ static void list_ports(snd_seq_t *seq, char *group, int perm, int list_subs)
 }
 
 
+static void print_port(snd_seq_t *seq, snd_seq_client_info_t *cinfo,
+                      snd_seq_port_info_t *pinfo, int count)
+{
+       if (! count) {
+               printf("client %d: '%s' [group=%s] [type=%s]\n",
+                      cinfo->client, cinfo->name, cinfo->group,
+                      (cinfo->type == USER_CLIENT ? "user" : "kernel"));
+       }
+       printf("  %3d '%-16s' [group=%s]\n",
+              pinfo->port, pinfo->name, pinfo->group);
+}
+
+static void print_port_and_subs(snd_seq_t *seq, snd_seq_client_info_t *cinfo,
+                               snd_seq_port_info_t *pinfo, int count)
+{
+       print_port(seq, cinfo, pinfo, count);
+       list_subscribers(seq, pinfo->client, pinfo->port);
+}
+
+
+/*
+ * list all ports
+ */
+
+static void list_ports(snd_seq_t *seq, char *group, int perm, int list_subs)
+{
+       if (list_subs)
+               do_search_port(seq, group, perm, print_port_and_subs);
+       else
+               do_search_port(seq, group, perm, print_port);
+}
+
+/*
+ * remove all (exported) connections
+ */
+static void remove_connection(snd_seq_t *seq, snd_seq_client_info_t *cinfo,
+                             snd_seq_port_info_t *pinfo, int count)
+{
+       snd_seq_query_subs_t query;
+
+       memset(&query, 0, sizeof(query));
+       query.client = pinfo->client;
+       query.port = pinfo->port;
+
+       query.type = SND_SEQ_QUERY_SUBS_READ;
+       query.index = 0;
+       for (query.index = 0; snd_seq_query_port_subscribers(seq, &query) >= 0;
+            query.index++) {
+               snd_seq_port_info_t port;
+               snd_seq_port_subscribe_t subs;
+               if (snd_seq_get_any_port_info(seq, query.addr.client, query.addr.port, &port) < 0)
+                       continue;
+               if (port.capability & SND_SEQ_PORT_CAP_NO_EXPORT)
+                       continue;
+               memset(&subs, 0, sizeof(subs));
+               subs.queue = query.queue;
+               subs.sender.client = query.client;
+               subs.sender.port = query.port;
+               subs.dest.client = query.addr.client;
+               subs.dest.port = query.addr.port;
+               snd_seq_unsubscribe_port(seq, &subs);
+       }
+
+       query.type = SND_SEQ_QUERY_SUBS_WRITE;
+       query.index = 0;
+       for (query.index = 0; snd_seq_query_port_subscribers(seq, &query) >= 0;
+            query.index++) {
+               snd_seq_port_info_t port;
+               snd_seq_port_subscribe_t subs;
+               if (snd_seq_get_any_port_info(seq, query.addr.client, query.addr.port, &port) < 0)
+                       continue;
+               if (port.capability & SND_SEQ_PORT_CAP_NO_EXPORT)
+                       continue;
+               memset(&subs, 0, sizeof(subs));
+               subs.queue = query.queue;
+               subs.sender.client = query.addr.client;
+               subs.sender.port = query.addr.port;
+               subs.dest.client = query.client;
+               subs.dest.port = query.port;
+               snd_seq_unsubscribe_port(seq, &subs);
+       }
+}
+
+static void remove_all_connections(snd_seq_t *seq)
+{
+       do_search_port(seq, "", 0, remove_connection);
+}
+
+
+/*
+ * main..
+ */
+
 enum {
-       SUBSCRIBE, UNSUBSCRIBE, LIST_INPUT, LIST_OUTPUT
+       SUBSCRIBE, UNSUBSCRIBE, LIST_INPUT, LIST_OUTPUT, REMOVE_ALL
 };
 
 static struct option long_option[] = {
@@ -170,6 +260,7 @@ static struct option long_option[] = {
        {"tick", 1, NULL, 't'},
        {"exclusive", 0, NULL, 'e'},
        {"list", 0, NULL, 'l'},
+       {"removeall", 0, NULL, 'x'},
        {NULL, 0, NULL, 0},
 };
 
@@ -185,7 +276,7 @@ int main(int argc, char **argv)
        snd_seq_client_info_t cinfo;
        snd_seq_port_subscribe_t subs;
 
-       while ((c = getopt_long(argc, argv, "diog:r:t:el", long_option, NULL)) != -1) {
+       while ((c = getopt_long(argc, argv, "diog:r:t:elx", long_option, NULL)) != -1) {
                switch (c) {
                case 'd':
                        command = UNSUBSCRIBE;
@@ -215,6 +306,9 @@ int main(int argc, char **argv)
                case 'l':
                        list_subs = 1;
                        break;
+               case 'x':
+                       command = REMOVE_ALL;
+                       break;
                default:
                        usage();
                        exit(1);
@@ -226,16 +320,23 @@ int main(int argc, char **argv)
                return 1;
        }
        
-       if (command == LIST_INPUT) {
+       switch (command) {
+       case LIST_INPUT:
                list_ports(seq, group, SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ, list_subs);
                snd_seq_close(seq);
                return 0;
-       } else if (command == LIST_OUTPUT) {
+       case LIST_OUTPUT:
                list_ports(seq, group, SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE, list_subs);
                snd_seq_close(seq);
                return 0;
+       case REMOVE_ALL:
+               remove_all_connections(seq);
+               snd_seq_close(seq);
+               return 0;
        }
 
+       /* connection or disconnection */
+
        if (optind + 2 > argc) {
                snd_seq_close(seq);
                usage();