[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.80 and 1.81

version 1.80, 2010/01/14 17:43:55 version 1.81, 2010/04/03 17:40:33
Line 43 
Line 43 
 #include "dbg.h"  #include "dbg.h"
 #endif  #endif
   
 #define MODE_PLAY       1  
 #define MODE_REC        2  
   
 #define PROG_AUCAT      "aucat"  #define PROG_AUCAT      "aucat"
 #define PROG_MIDICAT    "midicat"  #define PROG_MIDICAT    "midicat"
   
Line 159 
Line 156 
         errx(1, "%s: bad underrun/overrun policy", optarg);          errx(1, "%s: bad underrun/overrun policy", optarg);
 }  }
   
 int  unsigned
 opt_mode(void)  opt_mode(void)
 {  {
         if (strcmp("play", optarg) == 0)          unsigned mode = 0;
                 return MODE_PLAY;          char *p = optarg;
         if (strcmp("rec", optarg) == 0)          size_t len;
                 return MODE_REC;  
         if (strcmp("duplex", optarg) == 0)          for (p = optarg; *p != NULL; p++) {
                 return MODE_PLAY | MODE_REC;                  len = strcspn(p, ",");
         errx(1, "%s: bad mode", optarg);                  if (strncmp("play", p, len) == 0) {
                           mode |= MODE_PLAY;
                   } else if (strncmp("rec", p, len) == 0) {
                           mode |= MODE_REC;
                   } else if (strncmp("mon", p, len) == 0) {
                           mode |= MODE_MON;
                   } else if (strncmp("duplex", p, len) == 0) {
                           /* XXX: backward compat, remove this */
                           mode |= MODE_REC | MODE_PLAY;
                   } else
                           errx(1, "%s: bad mode", optarg);
                   p += len;
                   if (*p == '\0')
                           break;
           }
           if (mode == 0)
                   errx(1, "empty mode");
           return mode;
 }  }
   
 /*  /*
Line 183 
Line 197 
         int hdr;                /* header format */          int hdr;                /* header format */
         int xrun;               /* overrun/underrun policy */          int xrun;               /* overrun/underrun policy */
         int mmc;                /* MMC mode */          int mmc;                /* MMC mode */
           unsigned mode;
 };  };
   
 SLIST_HEAD(farglist, farg);  SLIST_HEAD(farglist, farg);
Line 194 
Line 209 
 void  void
 farg_add(struct farglist *list,  farg_add(struct farglist *list,
     struct aparams *ipar, struct aparams *opar, unsigned vol,      struct aparams *ipar, struct aparams *opar, unsigned vol,
     int hdr, int xrun, int mmc, char *name)      int hdr, int xrun, int mmc, unsigned mode, char *name)
 {  {
         struct farg *fa;          struct farg *fa;
         size_t namelen;          size_t namelen;
Line 212 
Line 227 
                 }                  }
         } else          } else
                 fa->hdr = hdr;                  fa->hdr = hdr;
           if (mmc && xrun == XRUN_IGNORE)
                   xrun = XRUN_SYNC;
         fa->xrun = xrun;          fa->xrun = xrun;
         fa->ipar = *ipar;          fa->ipar = *ipar;
         fa->opar = *opar;          fa->opar = *opar;
         fa->vol = vol;          fa->vol = vol;
         fa->name = name;          fa->name = name;
         fa->mmc = mmc;          fa->mmc = mmc;
           fa->mode = mode;
         SLIST_INSERT_HEAD(list, fa, entry);          SLIST_INSERT_HEAD(list, fa, entry);
 }  }
   
Line 287 
Line 305 
 }  }
   
 void  void
   stopall(char *base)
   {
           struct file *f;
   
     restart:
           LIST_FOREACH(f, &file_list, entry) {
                   /*
                    * skip connected streams (handled by dev_done())
                    */
                   if (APROC_OK(dev_mix) && f->rproc &&
                       aproc_depend(dev_mix, f->rproc))
                           continue;
                   if (APROC_OK(dev_sub) && f->wproc &&
                       aproc_depend(f->wproc, dev_sub))
                           continue;
                   if (APROC_OK(dev_midi)) {
                           if (f->rproc && aproc_depend(dev_midi, f->rproc))
                                   continue;
                           if (f->wproc && aproc_depend(f->wproc, dev_midi))
                                   continue;
                   }
                   /*
                    * kill anything else
                    */
                   file_close(f);
                   goto restart;
           }
   }
   
   void
 aucat_usage(void)  aucat_usage(void)
 {  {
         (void)fputs("usage: " PROG_AUCAT " [-dlnu] [-b nframes] "          (void)fputs("usage: " PROG_AUCAT " [-dlnu] [-b nframes] "
             "[-C min:max] [-c min:max] [-e enc] [-f device]\n"              "[-C min:max] [-c min:max] [-e enc]\n\t"
             "\t[-h fmt] [-i file] [-m mode] [-o file] [-r rate] [-s name]\n"              "[-f device] [-h fmt] [-i file] [-m mode]"
             "\t[-t mode] [-U unit] [-v volume] [-x policy] [-z nframes]\n",              "[-o file] [-q device]\n\t"
               "[-r rate] [-s name] [-t mode] [-U unit] "
               "[-v volume] [-x policy]\n\t"
               "[-z nframes]\n",
             stderr);              stderr);
 }  }
   
 int  int
 aucat_main(int argc, char **argv)  aucat_main(int argc, char **argv)
 {  {
         int c, u_flag, d_flag, l_flag, n_flag, hdr, xrun, suspend = 0, unit;          int c, u_flag, d_flag, l_flag, n_flag, hdr, xrun, unit;
         struct farg *fa;          struct farg *fa;
         struct farglist ifiles, ofiles, sfiles;          struct farglist ifiles, ofiles, sfiles, qfiles;
         struct aparams ipar, opar, dipar, dopar;          struct aparams ipar, opar, dipar, dopar;
         char base[PATH_MAX], path[PATH_MAX], *file;          char base[PATH_MAX], path[PATH_MAX], *file;
         unsigned bufsz, round, mode;          unsigned bufsz, round, mode;
         char *devpath;          char *devpath;
         const char *str;          const char *str;
         unsigned volctl;          unsigned volctl;
         int mmc;          int mmc, autostart;
   
         aparams_init(&ipar, 0, 1, 44100);          aparams_init(&ipar, 0, 1, 44100);
         aparams_init(&opar, 0, 1, 44100);          aparams_init(&opar, 0, 1, 44100);
Line 322 
Line 373 
         SLIST_INIT(&ifiles);          SLIST_INIT(&ifiles);
         SLIST_INIT(&ofiles);          SLIST_INIT(&ofiles);
         SLIST_INIT(&sfiles);          SLIST_INIT(&sfiles);
           SLIST_INIT(&qfiles);
         hdr = HDR_AUTO;          hdr = HDR_AUTO;
         xrun = XRUN_IGNORE;          xrun = XRUN_IGNORE;
         volctl = MIDI_MAXCTL;          volctl = MIDI_MAXCTL;
         mode = 0;          mode = MODE_PLAY | MODE_REC;
         bufsz = 0;          bufsz = 0;
         round = 0;          round = 0;
           autostart = 1;
   
         while ((c = getopt(argc, argv, "dnb:c:C:e:r:h:x:v:i:o:f:m:lus:U:t:z:")) != -1) {          while ((c = getopt(argc, argv, "dnb:c:C:e:r:h:x:v:i:o:f:m:luq:s:U:t:z:")) != -1) {
                 switch (c) {                  switch (c) {
                 case 'd':                  case 'd':
 #ifdef DEBUG  #ifdef DEBUG
Line 352 
Line 405 
                         break;                          break;
                 case 't':                  case 't':
                         mmc = opt_mmc();                          mmc = opt_mmc();
                           if (mmc)
                                   autostart = 0;
                         break;                          break;
                 case 'c':                  case 'c':
                         opt_ch(&ipar);                          opt_ch(&ipar);
Line 379 
Line 434 
                         if (strcmp(file, "-") == 0)                          if (strcmp(file, "-") == 0)
                                 file = NULL;                                  file = NULL;
                         farg_add(&ifiles, &ipar, &opar, volctl,                          farg_add(&ifiles, &ipar, &opar, volctl,
                             hdr, xrun, 0, file);                              hdr, xrun, mmc, mode & MODE_PLAY, file);
                         break;                          break;
                 case 'o':                  case 'o':
                         file = optarg;                          file = optarg;
                         if (strcmp(file, "-") == 0)                          if (strcmp(file, "-") == 0)
                                 file = NULL;                                  file = NULL;
                         farg_add(&ofiles, &ipar, &opar, volctl,                          farg_add(&ofiles, &ipar, &opar, volctl,
                             hdr, xrun, 0, file);                              hdr, xrun, mmc, mode & MODE_RECMASK, file);
                         break;                          break;
                 case 's':                  case 's':
                         farg_add(&sfiles, &ipar, &opar, volctl,                          farg_add(&sfiles, &ipar, &opar, volctl,
                             hdr, xrun, mmc, optarg);                              hdr, xrun, mmc, mode, optarg);
                         break;                          break;
                   case 'q':
                           farg_add(&qfiles, &aparams_none, &aparams_none,
                               0, HDR_RAW, 0, 0, 0, optarg);
                           break;
                 case 'f':                  case 'f':
                         if (devpath)                          if (devpath)
                                 err(1, "only one -f allowed");                                  err(1, "only one -f allowed");
Line 401 
Line 460 
                         break;                          break;
                 case 'l':                  case 'l':
                         l_flag = 1;                          l_flag = 1;
                           autostart = 0;
                         break;                          break;
                 case 'u':                  case 'u':
                         u_flag = 1;                          u_flag = 1;
Line 451 
Line 511 
   
         if (!l_flag && (!SLIST_EMPTY(&sfiles) || unit >= 0))          if (!l_flag && (!SLIST_EMPTY(&sfiles) || unit >= 0))
                 errx(1, "can't use -s or -U without -l");                  errx(1, "can't use -s or -U without -l");
         if ((l_flag || mode != 0) &&          if (l_flag && (!SLIST_EMPTY(&ofiles) || !SLIST_EMPTY(&ifiles)))
             (!SLIST_EMPTY(&ofiles) || !SLIST_EMPTY(&ifiles)))                  errx(1, "can't use -l, and -s with -o or -i");
                 errx(1, "can't use -l, -m and -s with -o or -i");  
         if (!mode) {  
                 if (l_flag || !SLIST_EMPTY(&ifiles))  
                         mode |= MODE_PLAY;  
                 if (l_flag || !SLIST_EMPTY(&ofiles))  
                         mode |= MODE_REC;  
                 if (!mode) {  
                         aucat_usage();  
                         exit(1);  
                 }  
         }  
         if (n_flag) {          if (n_flag) {
                 if (devpath != NULL || l_flag)                  if (devpath != NULL || !SLIST_EMPTY(&qfiles) ||
                         errx(1, "can't use -n with -f or -l");                      l_flag || !autostart)
                           errx(1, "can't use -n with -f, -q, -t or -l");
                 if (SLIST_EMPTY(&ifiles) || SLIST_EMPTY(&ofiles))                  if (SLIST_EMPTY(&ifiles) || SLIST_EMPTY(&ofiles))
                         errx(1, "both -i and -o are required with -n");                          errx(1, "both -i and -o are required with -n");
         }          }
Line 476 
Line 526 
          */           */
         if (l_flag && SLIST_EMPTY(&sfiles)) {          if (l_flag && SLIST_EMPTY(&sfiles)) {
                 farg_add(&sfiles, &dopar, &dipar,                  farg_add(&sfiles, &dopar, &dipar,
                     volctl, HDR_RAW, XRUN_IGNORE, mmc, DEFAULT_OPT);                      volctl, HDR_RAW, XRUN_IGNORE, mmc, mode, DEFAULT_OPT);
         }          }
   
         if (!u_flag) {          /*
                 /*           * Check modes and calculate "best" device parameters. Iterate over all
                  * 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           * number.
                  * and channel number.           */
                  */          mode = 0;
                 aparams_init(&dipar, dipar.cmin, dipar.cmax, dipar.rate);          aparams_init(&dipar, dipar.cmin, dipar.cmax, dipar.rate);
                 aparams_init(&dopar, dopar.cmin, dopar.cmax, dopar.rate);          aparams_init(&dopar, dopar.cmin, dopar.cmax, dopar.rate);
                 SLIST_FOREACH(fa, &ifiles, entry) {          SLIST_FOREACH(fa, &ifiles, entry) {
                   if (fa->mode == 0)
                           errx(1, "%s: not in play mode", fa->name);
                   mode |= fa->mode;
                   if (!u_flag)
                         aparams_grow(&dopar, &fa->ipar);                          aparams_grow(&dopar, &fa->ipar);
                 }          }
                 SLIST_FOREACH(fa, &ofiles, entry) {          SLIST_FOREACH(fa, &ofiles, entry) {
                   if (fa->mode == 0)
                           errx(1, "%s: not in rec/mon mode", fa->name);
                   if ((fa->mode & MODE_REC) && (fa->mode & MODE_MON))
                           errx(1, "%s: can't record and monitor", fa->name);
                   mode |= fa->mode;
                   if (!u_flag)
                         aparams_grow(&dipar, &fa->opar);                          aparams_grow(&dipar, &fa->opar);
                 }          }
                 SLIST_FOREACH(fa, &sfiles, entry) {          SLIST_FOREACH(fa, &sfiles, entry) {
                   if ((fa->mode & MODE_REC) && (fa->mode & MODE_MON))
                           errx(1, "%s: can't record and monitor", fa->name);
                   mode |= fa->mode;
                   if (!u_flag) {
                         aparams_grow(&dopar, &fa->ipar);                          aparams_grow(&dopar, &fa->ipar);
                         aparams_grow(&dipar, &fa->opar);                          aparams_grow(&dipar, &fa->opar);
                 }                  }
         }          }
   
         if (!round)          if (!round)
                 round = ((mode & MODE_REC) ? dipar.rate : dopar.rate) / 15;                  round = ((mode & MODE_REC) ? dipar.rate : dopar.rate) / 15;
         if (!bufsz)          if (!bufsz)
Line 516 
Line 581 
          * the other half is for the socket/files.           * the other half is for the socket/files.
          */           */
         if (n_flag) {          if (n_flag) {
                   if (mode & MODE_MON)
                           errx(1, "monitoring not allowed in loopback mode");
                 dev_loopinit(&dipar, &dopar, bufsz);                  dev_loopinit(&dipar, &dopar, bufsz);
         } else {          } else {
                 if (!dev_init(devpath,                  if ((mode & MODE_MON) && !(mode & MODE_PLAY))
                         (mode & MODE_REC) ? &dipar : NULL,                          errx(1, "no playback stream to monitor");
                         (mode & MODE_PLAY) ? &dopar : NULL,                  if (!dev_init(devpath, mode, &dipar, &dopar, bufsz, round)) {
                         bufsz, round)) {  
                         errx(1, "%s: can't open device",                          errx(1, "%s: can't open device",
                             devpath ? devpath : "<default>");                              devpath ? devpath : "<default>");
                 }                  }
Line 530 
Line 596 
         /*          /*
          * Create buffers for all input and output pipes.           * Create buffers for all input and output pipes.
          */           */
           while (!SLIST_EMPTY(&qfiles)) {
                   fa = SLIST_FIRST(&qfiles);
                   SLIST_REMOVE_HEAD(&qfiles, entry);
                   if (!dev_thruadd(fa->name, 1, 1))
                           errx(1, "%s: can't open device", fa->name);
                   free(fa);
           }
         while (!SLIST_EMPTY(&ifiles)) {          while (!SLIST_EMPTY(&ifiles)) {
                 fa = SLIST_FIRST(&ifiles);                  fa = SLIST_FIRST(&ifiles);
                 SLIST_REMOVE_HEAD(&ifiles, entry);                  SLIST_REMOVE_HEAD(&ifiles, entry);
                 if (!wav_new_in(&wav_ops, fa->name,                  if (!wav_new_in(&wav_ops, fa->mode, fa->name,
                         fa->hdr, &fa->ipar, fa->xrun, fa->vol))                          fa->hdr, &fa->ipar, fa->xrun, fa->vol, fa->mmc))
                         exit(1);                          exit(1);
                 free(fa);                  free(fa);
         }          }
         while (!SLIST_EMPTY(&ofiles)) {          while (!SLIST_EMPTY(&ofiles)) {
                 fa = SLIST_FIRST(&ofiles);                  fa = SLIST_FIRST(&ofiles);
                 SLIST_REMOVE_HEAD(&ofiles, entry);                  SLIST_REMOVE_HEAD(&ofiles, entry);
                 if (!wav_new_out(&wav_ops, fa->name,                  if (!wav_new_out(&wav_ops, fa->mode, fa->name,
                         fa->hdr, &fa->opar, fa->xrun))                          fa->hdr, &fa->opar, fa->xrun, fa->mmc))
                 free(fa);                  free(fa);
         }          }
         while (!SLIST_EMPTY(&sfiles)) {          while (!SLIST_EMPTY(&sfiles)) {
                 fa = SLIST_FIRST(&sfiles);                  fa = SLIST_FIRST(&sfiles);
                 SLIST_REMOVE_HEAD(&sfiles, entry);                  SLIST_REMOVE_HEAD(&sfiles, entry);
                 opt_new(fa->name, &fa->opar, &fa->ipar,                  opt_new(fa->name, &fa->opar, &fa->ipar,
                     MIDI_TO_ADATA(fa->vol), fa->mmc);                      MIDI_TO_ADATA(fa->vol), fa->mmc, fa->mode);
                 free(fa);                  free(fa);
         }          }
         if (l_flag) {          if (l_flag) {
Line 559 
Line 632 
                 if (!d_flag && daemon(0, 0) < 0)                  if (!d_flag && daemon(0, 0) < 0)
                         err(1, "daemon");                          err(1, "daemon");
         }          }
           if (autostart) {
                   /*
                    * inject artificial mmc start
                    */
                   ctl_start(dev_midi);
           }
           if (l_flag)
                   dev_prime();
   
         /*          /*
          * Loop, start audio.           * Loop, start audio.
Line 567 
Line 648 
                 if (quit_flag) {                  if (quit_flag) {
                         break;                          break;
                 }                  }
                 if ((dev_mix && LIST_EMPTY(&dev_mix->obuflist)) ||                  if ((APROC_OK(dev_mix) && LIST_EMPTY(&dev_mix->obuflist)) ||
                     (dev_sub && LIST_EMPTY(&dev_sub->ibuflist))) {                      (APROC_OK(dev_sub) && LIST_EMPTY(&dev_sub->ibuflist))) {
                         fprintf(stderr, "device disappeared, terminating\n");                          fprintf(stderr, "device disappeared, terminating\n");
                         break;                          break;
                 }                  }
                   if (!l_flag && ctl_idle(dev_midi))
                           break;
                 if (!file_poll())                  if (!file_poll())
                         break;                          break;
                 if ((!dev_mix || dev_mix->u.mix.idle > 2 * dev_bufsz) &&                  if ((!APROC_OK(dev_mix)    || dev_mix->u.mix.idle > 2 * dev_bufsz) &&
                     (!dev_sub || dev_sub->u.sub.idle > 2 * dev_bufsz) &&                      (!APROC_OK(dev_sub)    || dev_sub->u.sub.idle > 2 * dev_bufsz) &&
                     ((dev_mix || dev_sub) && dev_midi->u.ctl.tstate != CTL_RUN)) {                      (!APROC_OK(dev_submon) || dev_submon->u.sub.idle > 2 * dev_bufsz) &&
                         if (!l_flag)                      (!APROC_OK(dev_midi)   || dev_midi->u.ctl.tstate != CTL_RUN)) {
                                 break;                          if (dev_pstate == DEV_RUN) {
                         if (!suspend) {                                  dev_pstate = DEV_INIT;
 #ifdef DEBUG  
                                 if (debug_level >= 2)  
                                         dbg_puts("suspending\n");  
 #endif  
                                 suspend = 1;  
                                 dev_stop();                                  dev_stop();
                                 dev_clear();                                  dev_clear();
                                 dev_prime();                                  /*
                                    * priming buffer in non-server mode is not
                                    * ok, because it will insert silence and
                                    * break synchronization
                                    */
                                   if (l_flag)
                                           dev_prime();
                         }                          }
                 }                  }
                 if ((dev_mix && dev_mix->u.mix.idle == 0) ||                  /*
                     (dev_sub && dev_sub->u.sub.idle == 0) ||                   * move device state machine
                     ((dev_mix || dev_sub) && dev_midi->u.ctl.tstate == CTL_RUN)) {                   * XXX: move this to dev.c
                         if (suspend) {                   */
 #ifdef DEBUG                  if (dev_pstate == DEV_START) {
                                 if (debug_level >= 2)                          dev_pstate = DEV_RUN;
                                         dbg_puts("resuming\n");                          dev_start();
 #endif  
                                 suspend = 0;  
                                 dev_start();  
                         }  
                 }                  }
         }          }
           stopall(base);
           dev_done();
           filelist_done();
         if (l_flag) {          if (l_flag) {
                 filelist_unlisten();                  if (rmdir(base) < 0 && errno != ENOTEMPTY)
                 if (rmdir(base) < 0)  
                         warn("rmdir(\"%s\")", base);                          warn("rmdir(\"%s\")", base);
         }          }
         if (suspend) {  
 #ifdef DEBUG  
                 if (debug_level >= 2)  
                         dbg_puts("resuming to drain\n");  
 #endif  
                 suspend = 0;  
                 dev_start();  
         }  
         dev_done();  
         filelist_done();  
         unsetsig();          unsetsig();
         return 0;          return 0;
 }  }
Line 625 
Line 697 
 void  void
 midicat_usage(void)  midicat_usage(void)
 {  {
         (void)fputs("usage: " PROG_MIDICAT " [-dl] [-f device] "          (void)fputs("usage: " PROG_MIDICAT " [-dl] "
             "[-i file] [-o file] [-U unit]\n",              "[-i file] [-o file] [-q device] [-U unit]\n",
             stderr);              stderr);
 }  }
 int  int
Line 648 
Line 720 
         SLIST_INIT(&ifiles);          SLIST_INIT(&ifiles);
         SLIST_INIT(&ofiles);          SLIST_INIT(&ofiles);
   
         while ((c = getopt(argc, argv, "di:o:lf:U:")) != -1) {          while ((c = getopt(argc, argv, "di:o:lf:q:U:")) != -1) {
                 switch (c) {                  switch (c) {
                 case 'd':                  case 'd':
 #ifdef DEBUG  #ifdef DEBUG
Line 659 
Line 731 
                         break;                          break;
                 case 'i':                  case 'i':
                         farg_add(&ifiles, &aparams_none, &aparams_none,                          farg_add(&ifiles, &aparams_none, &aparams_none,
                             0, HDR_RAW, 0, 0, optarg);                              0, HDR_RAW, 0, 0, 0, optarg);
                         break;                          break;
                 case 'o':                  case 'o':
                         farg_add(&ofiles, &aparams_none, &aparams_none,                          farg_add(&ofiles, &aparams_none, &aparams_none,
                             0, HDR_RAW, 0, 0, optarg);                              0, HDR_RAW, 0, 0, 0, optarg);
                         break;                          break;
                 case 'f':                          /* XXX: backward compat, remove this */
                   case 'f':
                   case 'q':
                         farg_add(&dfiles, &aparams_none, &aparams_none,                          farg_add(&dfiles, &aparams_none, &aparams_none,
                             0, HDR_RAW, 0, 0, optarg);                              0, HDR_RAW, 0, 0, 0, optarg);
                         break;                          break;
                 case 'l':                  case 'l':
                         l_flag = 1;                          l_flag = 1;
Line 703 
Line 777 
         filelist_init();          filelist_init();
   
         dev_thruinit();          dev_thruinit();
         if (!l_flag)          if (!l_flag && APROC_OK(dev_midi))
                 dev_midi->flags |= APROC_QUIT;                  dev_midi->flags |= APROC_QUIT;
         if ((!SLIST_EMPTY(&ifiles) || !SLIST_EMPTY(&ofiles)) &&          if ((!SLIST_EMPTY(&ifiles) || !SLIST_EMPTY(&ofiles)) &&
             SLIST_EMPTY(&dfiles)) {              SLIST_EMPTY(&dfiles)) {
                 farg_add(&dfiles, &aparams_none, &aparams_none,                  farg_add(&dfiles, &aparams_none, &aparams_none,
                     0, HDR_RAW, 0, 0, NULL);                      0, HDR_RAW, 0, 0, 0, NULL);
         }          }
         while (!SLIST_EMPTY(&dfiles)) {          while (!SLIST_EMPTY(&dfiles)) {
                 fa = SLIST_FIRST(&dfiles);                  fa = SLIST_FIRST(&dfiles);
Line 767 
Line 841 
                 dev_midiattach(NULL, buf);                  dev_midiattach(NULL, buf);
                 free(fa);                  free(fa);
         }          }
   
         /*          /*
          * loop, start processing           * loop, start processing
          */           */
Line 778 
Line 851 
                 if (!file_poll())                  if (!file_poll())
                         break;                          break;
         }          }
           stopall(base);
           dev_done();
           filelist_done();
         if (l_flag) {          if (l_flag) {
                 filelist_unlisten();                  if (rmdir(base) < 0 && errno != ENOTEMPTY)
                 if (rmdir(base) < 0)  
                         warn("rmdir(\"%s\")", base);                          warn("rmdir(\"%s\")", base);
         }          }
         dev_done();  
         filelist_done();  
         unsetsig();          unsetsig();
         return 0;          return 0;
 }  }

Legend:
Removed from v.1.80  
changed lines
  Added in v.1.81