[BACK]Return to aucat.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / aucat

Diff for /src/usr.bin/aucat/aucat.c between version 1.97 and 1.98

version 1.97, 2010/06/29 06:48:39 version 1.98, 2010/07/06 01:12:45
Line 434 
Line 434 
         int autostart, legacy;          int autostart, legacy;
         struct dev *d, *dnext;          struct dev *d, *dnext;
         unsigned active;          unsigned active;
           unsigned nsock, nfile;
   
         /*          /*
          * global options defaults           * global options defaults
Line 446 
Line 447 
         legacy = 1;          legacy = 1;
         legacy_path = NULL;          legacy_path = NULL;
         SLIST_INIT(&cfdevs);          SLIST_INIT(&cfdevs);
           nfile = nsock = 0;
   
         /*          /*
          * default stream params           * default stream params
Line 561 
Line 563 
                 case 'i':                  case 'i':
                         legacy = 0;                          legacy = 0;
                         cfstr_add(&cd->ins, cs, optarg);                          cfstr_add(&cd->ins, cs, optarg);
                           nfile++;
                         break;                          break;
                 case 'o':                  case 'o':
                         legacy = 0;                          legacy = 0;
                         cfstr_add(&cd->outs, cs, optarg);                          cfstr_add(&cd->outs, cs, optarg);
                           nfile++;
                         break;                          break;
                 case 's':                  case 's':
                         legacy = 0;                          legacy = 0;
                         cfstr_add(&cd->opts, cs, optarg);                          cfstr_add(&cd->opts, cs, optarg);
                           nsock++;
                         break;                          break;
                 case 'a':                  case 'a':
                         legacy = 0;                          legacy = 0;
Line 593 
Line 598 
                 case 'f':                  case 'f':
                         legacy = 0;                          legacy = 0;
                         legacy_path = optarg;                          legacy_path = optarg;
                           if (SLIST_EMPTY(&cd->opts) &&
                               SLIST_EMPTY(&cd->ins) &&
                               SLIST_EMPTY(&cd->outs)) {
                                   cfstr_add(&cd->opts, cs, DEFAULT_OPT);
                                   nsock++;
                           }
                         cfdev_add(&cfdevs, cd, optarg);                          cfdev_add(&cfdevs, cd, optarg);
                         break;                          break;
                 case 'l':                  case 'l':
Line 624 
Line 635 
                 exit(0);                  exit(0);
         }          }
   
         if (!l_flag && unit >= 0)          /*
                 errx(1, "can't use -U without -l");           * Check constraints specific to -n option
            */
         if (n_flag) {          if (n_flag) {
                 if (!SLIST_EMPTY(&cfdevs) || l_flag ||                  if (!SLIST_EMPTY(&cfdevs) ||
                     !SLIST_EMPTY(&cd->opts) || !SLIST_EMPTY(&cd->mids))                      !SLIST_EMPTY(&cd->mids) ||
                         errx(1, "can't use -n with -l, -f, -q or -s");                      !SLIST_EMPTY(&cd->opts))
                           errx(1, "-f, -s, and -q not allowed in loopback mode");
                 if (SLIST_EMPTY(&cd->ins) || SLIST_EMPTY(&cd->outs))                  if (SLIST_EMPTY(&cd->ins) || SLIST_EMPTY(&cd->outs))
                         errx(1, "both -i and -o are required with -n");                          errx(1, "-i and -o are required in loopback mode");
         }          }
   
         /*          /*
          * if no device is given, add the default one           * If there's no device specified, do as if the default
            * device is specified as last argument.
          */           */
         if (SLIST_EMPTY(&cfdevs)) {          if (SLIST_EMPTY(&cfdevs)) {
                   if (SLIST_EMPTY(&cd->opts) &&
                       SLIST_EMPTY(&cd->ins) &&
                       SLIST_EMPTY(&cd->outs)) {
                           cfstr_add(&cd->opts, cs, DEFAULT_OPT);
                           nsock++;
                   }
                 if (!cd->hold)                  if (!cd->hold)
                         errx(1, "-a not compatible with default device");                          errx(1, "-a off not compatible with default device");
                 cfdev_add(&cfdevs, cd, "default");                  cfdev_add(&cfdevs, cd, "default");
         }          }
           if ((cs = SLIST_FIRST(&cd->opts)) ||
               (cs = SLIST_FIRST(&cd->ins)) ||
               (cs = SLIST_FIRST(&cd->outs)))
                   errx(1, "%s: no device to attach the stream to", cs->path);
   
         /*          /*
          * If there are no sockets paths provided use the default.  
          */  
         if (l_flag) {  
                 SLIST_FOREACH(cd, &cfdevs, entry) {  
                         if (!SLIST_EMPTY(&cd->opts))  
                                 continue;  
                         cfstr_add(&cd->opts, cs, DEFAULT_OPT);  
                         break;  
                 }  
         }  
   
         /*  
          * Check modes and calculate "best" device parameters. Iterate over all           * Check modes and calculate "best" device parameters. Iterate over all
          * inputs and outputs and find the maximum sample rate and channel           * inputs and outputs and find the maximum sample rate and channel
          * number.           * number.
Line 687 
Line 699 
                                 aparams_grow(&cd->ipar, &cs->opar);                                  aparams_grow(&cd->ipar, &cs->opar);
                         }                          }
                 }                  }
                 if (l_flag && SLIST_EMPTY(&cd->opts))  
                         errx(1, "%s: no subdevs for this device", cd->path);  
                 if (!l_flag && SLIST_EMPTY(&cd->ins) && SLIST_EMPTY(&cd->outs))  
                         errx(1, "%s: no files for this device", cd->path);  
                 if (n_flag && (mode & MODE_MON))  
                         errx(1, "monitoring not allowed in loopback mode");  
                 if ((mode & MODE_MON) && !(mode & MODE_PLAY))                  if ((mode & MODE_MON) && !(mode & MODE_PLAY))
                         errx(1, "no playback stream to monitor");                          errx(1, "no playback stream to monitor");
                   if (n_flag && (mode & MODE_MON))
                           errx(1, "-m mon not allowed in loopback mode");
                 rate = (mode & MODE_REC) ? cd->ipar.rate : cd->opar.rate;                  rate = (mode & MODE_REC) ? cd->ipar.rate : cd->opar.rate;
                 if (!cd->round)                  if (!cd->round)
                         cd->round = rate / 15;                          cd->round = rate / 15;
Line 702 
Line 710 
                         cd->bufsz = rate / 15 * 4;                          cd->bufsz = rate / 15 * 4;
                 cd->mode = mode;                  cd->mode = mode;
         }          }
           if (nsock > 0) {
         if (l_flag) {  
                 getbasepath(base, sizeof(base));                  getbasepath(base, sizeof(base));
                 if (unit < 0)                  if (unit < 0)
                         unit = 0;                          unit = 0;
Line 781 
Line 788 
                         ctl_start(d->midi);                          ctl_start(d->midi);
                 }                  }
         }          }
         if (l_flag) {          if (nsock > 0) {
                 snprintf(path, sizeof(path), "%s/%s%u", base,                  snprintf(path, sizeof(path), "%s/%s%u", base,
                     DEFAULT_SOFTAUDIO, unit);                      DEFAULT_SOFTAUDIO, unit);
                 listen = listen_new(&listen_ops, path);                  listen = listen_new(&listen_ops, path);
                 if (listen == 0)                  if (listen == NULL)
                         exit(1);                          exit(1);
                 if (geteuid() == 0)          }
                         privdrop();          if (geteuid() == 0)
                 if (!d_flag && daemon(0, 0) < 0)                  privdrop();
           if (l_flag) {
                   debug_level = 0;
                   dbg_flush();
                   if (daemon(0, 0) < 0)
                         err(1, "daemon");                          err(1, "daemon");
         }          }
   
Line 809 
Line 820 
                 }                  }
                 if (dev_list == NULL)                  if (dev_list == NULL)
                         break;                          break;
                 if (!l_flag && !active)                  if (nsock == 0 && !active)
                         break;                          break;
                 if (!file_poll())                  if (!file_poll())
                         break;                          break;
         }          }
   fatal:    fatal:
         if (l_flag)          if (nsock > 0)
                 file_close(&listen->file);                  file_close(&listen->file);
         /*          /*
          * give a chance to drain           * give a chance to drain
Line 828 
Line 839 
         while (dev_list)          while (dev_list)
                 dev_del(dev_list);                  dev_del(dev_list);
         filelist_done();          filelist_done();
         if (l_flag) {          if (nsock > 0) {
                 if (rmdir(base) < 0 && errno != ENOTEMPTY && errno != EPERM)                  if (rmdir(base) < 0 && errno != ENOTEMPTY && errno != EPERM)
                         warn("rmdir(\"%s\")", base);                          warn("rmdir(\"%s\")", base);
         }          }
Line 847 
Line 858 
 int  int
 midicat_main(int argc, char **argv)  midicat_main(int argc, char **argv)
 {  {
         struct cfmidlist mids, ins, outs;          struct cfdevlist cfdevs;
         struct cfmid *cm;          struct cfmid *cm;
           struct cfstr *cs;
           struct cfdev *cd;
         struct listen *listen = NULL;          struct listen *listen = NULL;
         int c, d_flag, l_flag, unit, fd;          int c, d_flag, l_flag, unit, fd;
         char base[PATH_MAX], path[PATH_MAX];          char base[PATH_MAX], path[PATH_MAX];
Line 856 
Line 869 
         struct aproc *p;          struct aproc *p;
         struct abuf *buf;          struct abuf *buf;
         const char *str;          const char *str;
         struct dev *d;          struct dev *d, *dnext;
           unsigned nsock;
   
         /*          /*
          * global options defaults           * global options defaults
Line 864 
Line 878 
         unit = -1;          unit = -1;
         d_flag = 0;          d_flag = 0;
         l_flag = 0;          l_flag = 0;
         SLIST_INIT(&mids);          SLIST_INIT(&cfdevs);
         SLIST_INIT(&ins);          nsock = 0;
         SLIST_INIT(&outs);  
           /*
            * default stream params
            */
           cs = malloc(sizeof(struct cfstr));
           if (cs == NULL) {
                   perror("malloc");
                   exit(1);
           }
           cs->hdr = HDR_RAW;
   
         while ((c = getopt(argc, argv, "di:o:lf:q:U:")) != -1) {          /*
            * default device
            */
           cd = malloc(sizeof(struct cfdev));
           if (cd == NULL) {
                   perror("malloc");
                   exit(1);
           }
           SLIST_INIT(&cd->ins);
           SLIST_INIT(&cd->outs);
           SLIST_INIT(&cd->opts);
           SLIST_INIT(&cd->mids);
           cd->path = NULL;
   
   
           while ((c = getopt(argc, argv, "di:o:ls:q:U:")) != -1) {
                 switch (c) {                  switch (c) {
                 case 'd':                  case 'd':
 #ifdef DEBUG  #ifdef DEBUG
Line 878 
Line 916 
                         d_flag = 1;                          d_flag = 1;
                         break;                          break;
                 case 'i':                  case 'i':
                         cfmid_add(&ins, optarg);                          cfstr_add(&cd->ins, cs, optarg);
                         break;                          break;
                 case 'o':                  case 'o':
                         cfmid_add(&outs, optarg);                          cfstr_add(&cd->outs, cs, optarg);
                         break;                          break;
                         /* XXX: backward compat, remove this */  
                 case 'f':  
                 case 'q':                  case 'q':
                         cfmid_add(&mids, optarg);                          cfmid_add(&cd->mids, optarg);
                         break;                          break;
                   case 's':
                           cfstr_add(&cd->opts, cs, optarg);
                           cfdev_add(&cfdevs, cd, optarg);
                           nsock++;
                           break;
                 case 'l':                  case 'l':
                         l_flag = 1;                          l_flag = 1;
                         break;                          break;
Line 904 
Line 945 
         argc -= optind;          argc -= optind;
         argv += optind;          argv += optind;
   
         if (argc > 0 || (SLIST_EMPTY(&ins) && SLIST_EMPTY(&outs) && !l_flag)) {  #ifdef DEBUG
           if (debug_level == 0)
                   debug_level = 1;
   #endif
           if (argc > 0) {
                 midicat_usage();                  midicat_usage();
                 exit(1);                  exit(1);
         }          }
         if (!l_flag && unit >= 0)  
                 errx(1, "can't use -U without -l");          /*
         if (l_flag) {           * If there's no device specified (-s), then create one with
                 if (!SLIST_EMPTY(&ins) || !SLIST_EMPTY(&outs))           * reasonable defaults:
                         errx(1, "can't use -i or -o with -l");           *
            *  - if there are no streams (-ioq) defined, assume server mode
            *    and expose the "defaut" option
            *
            *  - if there are files (-io) but no ports (-q) to send/receive
            *    from, add the default sndio(7) MIDI port
            */
           if (SLIST_EMPTY(&cfdevs)) {
                   if (SLIST_EMPTY(&cd->mids)) {
                           if (SLIST_EMPTY(&cd->ins) && SLIST_EMPTY(&cd->outs))
                                   cfmid_add(&cd->mids, "default");
                           else {
                                   cfstr_add(&cd->opts, cs, DEFAULT_OPT);
                                   nsock++;
                           }
                   }
                   cfdev_add(&cfdevs, cd, "default");
           }
           if (nsock > 0) {
                 getbasepath(base, sizeof(path));                  getbasepath(base, sizeof(path));
                 if (unit < 0)                  if (unit < 0)
                         unit = 0;                          unit = 0;
Line 920 
Line 983 
         setsig();          setsig();
         filelist_init();          filelist_init();
   
         d = dev_new_thru();          while (!SLIST_EMPTY(&cfdevs)) {
         if (!dev_ref(d))                  cd = SLIST_FIRST(&cfdevs);
                 errx(1, "couldn't open midi thru box");                  SLIST_REMOVE_HEAD(&cfdevs, entry);
         if (!l_flag && APROC_OK(d->midi))  
                 d->midi->flags |= APROC_QUIT;                  d = dev_new_thru();
         if ((!SLIST_EMPTY(&ins) || !SLIST_EMPTY(&outs)) && SLIST_EMPTY(&mids)) {                  if (d == NULL)
                 cfmid_add(&mids, "default");                          errx(1, "%s: can't open device", cd->path);
         }                  if (!dev_ref(d))
         while (!SLIST_EMPTY(&mids)) {                          errx(1, "couldn't open midi thru box");
                 cm = SLIST_FIRST(&mids);                  if (!SLIST_EMPTY(&cd->opts) && APROC_OK(d->midi))
                 SLIST_REMOVE_HEAD(&mids, entry);                          d->midi->flags |= APROC_QUIT;
                 if (!dev_thruadd(d, cm->path,  
                         !SLIST_EMPTY(&outs) || l_flag,                  /*
                         !SLIST_EMPTY(&ins) || l_flag)) {                   * register midi ports
                         errx(1, "%s: can't open device", cm->path);                   */
                   while (!SLIST_EMPTY(&cd->mids)) {
                           cm = SLIST_FIRST(&cd->mids);
                           SLIST_REMOVE_HEAD(&cd->mids, entry);
                           if (!dev_thruadd(d, cm->path, 1, 1))
                                   errx(1, "%s: can't open device", cm->path);
                           free(cm);
                 }                  }
                 free(cm);  
                   /*
                    * register files
                    */
                   while (!SLIST_EMPTY(&cd->ins)) {
                           cs = SLIST_FIRST(&cd->ins);
                           SLIST_REMOVE_HEAD(&cd->ins, entry);
                           if (strcmp(cs->path, "-") == 0) {
                                   fd = STDIN_FILENO;
                                   if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0)
                                           warn("stdin");
                           } else {
                                   fd = open(cs->path, O_RDONLY | O_NONBLOCK, 0666);
                                   if (fd < 0)
                                           err(1, "%s", cs->path);
                           }
                           stdx = (struct file *)pipe_new(&pipe_ops, fd, cs->path);
                           p = rfile_new(stdx);
                           buf = abuf_new(MIDI_BUFSZ, &aparams_none);
                           aproc_setout(p, buf);
                           dev_midiattach(d, buf, NULL);
                           free(cs);
                   }
                   while (!SLIST_EMPTY(&cd->outs)) {
                           cs = SLIST_FIRST(&cd->outs);
                           SLIST_REMOVE_HEAD(&cd->outs, entry);
                           if (strcmp(cs->path, "-") == 0) {
                                   fd = STDOUT_FILENO;
                                   if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0)
                                           warn("stdout");
                           } else {
                                   fd = open(cs->path,
                                       O_WRONLY | O_TRUNC | O_CREAT | O_NONBLOCK, 0666);
                                   if (fd < 0)
                                           err(1, "%s", cs->path);
                           }
                           stdx = (struct file *)pipe_new(&pipe_ops, fd, cs->path);
                           p = wfile_new(stdx);
                           buf = abuf_new(MIDI_BUFSZ, &aparams_none);
                           aproc_setin(p, buf);
                           dev_midiattach(d, NULL, buf);
                           free(cs);
                   }
                   while (!SLIST_EMPTY(&cd->opts)) {
                           cs = SLIST_FIRST(&cd->opts);
                           SLIST_REMOVE_HEAD(&cd->opts, entry);
                           opt_new(cs->path, d, NULL, NULL, 0, 0, 0, 0);
                           free(cs);
                   }
                   free(cd);
         }          }
         if (l_flag) {          if (nsock > 0) {
                 opt_new(DEFAULT_OPT, d, NULL, NULL, 0, 0, 0, 0);  
                 snprintf(path, sizeof(path), "%s/%s%u", base,                  snprintf(path, sizeof(path), "%s/%s%u", base,
                     DEFAULT_MIDITHRU, unit);                      DEFAULT_MIDITHRU, unit);
                 listen = listen_new(&listen_ops, path);                  listen = listen_new(&listen_ops, path);
                 if (geteuid() == 0)                  if (listen == NULL)
                         privdrop();                          exit(1);
                 if (!d_flag && daemon(0, 0) < 0)          }
           if (geteuid() == 0)
                   privdrop();
           if (l_flag) {
                   debug_level = 0;
                   dbg_flush();
                   if (daemon(0, 0) < 0)
                         err(1, "daemon");                          err(1, "daemon");
         }          }
         while (!SLIST_EMPTY(&ins)) {  
                 cm = SLIST_FIRST(&ins);  
                 SLIST_REMOVE_HEAD(&ins, entry);  
                 if (strcmp(cm->path, "-") == 0) {  
                         fd = STDIN_FILENO;  
                         if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0)  
                                 warn("stdin");  
                 } else {  
                         fd = open(cm->path, O_RDONLY | O_NONBLOCK, 0666);  
                         if (fd < 0)  
                                 err(1, "%s", cm->path);  
                 }  
                 stdx = (struct file *)pipe_new(&pipe_ops, fd, cm->path);  
                 p = rfile_new(stdx);  
                 buf = abuf_new(MIDI_BUFSZ, &aparams_none);  
                 aproc_setout(p, buf);  
                 dev_midiattach(d, buf, NULL);  
                 free(cm);  
         }  
         while (!SLIST_EMPTY(&outs)) {  
                 cm = SLIST_FIRST(&outs);  
                 SLIST_REMOVE_HEAD(&outs, entry);  
                 if (strcmp(cm->path, "-") == 0) {  
                         fd = STDOUT_FILENO;  
                         if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0)  
                                 warn("stdout");  
                 } else {  
                         fd = open(cm->path,  
                             O_WRONLY | O_TRUNC | O_CREAT | O_NONBLOCK, 0666);  
                         if (fd < 0)  
                                 err(1, "%s", cm->path);  
                 }  
                 stdx = (struct file *)pipe_new(&pipe_ops, fd, cm->path);  
                 p = wfile_new(stdx);  
                 buf = abuf_new(MIDI_BUFSZ, &aparams_none);  
                 aproc_setin(p, buf);  
                 dev_midiattach(d, NULL, buf);  
                 free(cm);  
         }  
         /*          /*
          * loop, start processing           * loop, start processing
          */           */
         for (;;) {          for (;;) {
                 if (quit_flag)                  if (quit_flag)
                         break;                          break;
                 if (!dev_run(d))                  for (d = dev_list; d != NULL; d = dnext) {
                         break;                          dnext = d->next;
                           if (!dev_run(d))
                                   goto fatal;
                   }
                 if (!file_poll())                  if (!file_poll())
                         break;                          break;
         }          }
         if (l_flag)    fatal:
           if (nsock > 0)
                 file_close(&listen->file);                  file_close(&listen->file);
         dev_unref(d);  
         dev_del(d);  
         /*          /*
          * drain           * give a chance to drain
          */           */
           for (d = dev_list; d != NULL; d = d->next)
                   dev_drain(d);
         while (file_poll())          while (file_poll())
                 ; /* nothing */                  ; /* nothing */
   
           while (dev_list)
                   dev_del(dev_list);
         filelist_done();          filelist_done();
         if (l_flag) {          if (nsock > 0) {
                 if (rmdir(base) < 0 && errno != ENOTEMPTY && errno != EPERM)                  if (rmdir(base) < 0 && errno != ENOTEMPTY && errno != EPERM)
                         warn("rmdir(\"%s\")", base);                          warn("rmdir(\"%s\")", base);
         }          }

Legend:
Removed from v.1.97  
changed lines
  Added in v.1.98