On Thu, 2021-08-12 at 15:57 +0200, Ingo Schwarze wrote:
> Hi,
> 
> deraadt@ recently pointed out to me in private mail that it is good
> for usability if interactive programs providing line editing
> functionality are consistent what they do with Ctrl-C, ideally
> discard the current input line and provide a fresh prompt.
> At least that is what bc(1), ftp(1), sftp(1) and all shells do.
> 
> So i propose to do the same in cdio(1), which currently just exits
> on Ctrl-C.
> 
> Sending to tech@ because i'm not quite sure which developer owns cdio(1),
> or who might be interested.  According to the CVS logs, naddy@ was the
> last one to change user-visible functionality, and before that, there
> was nothing but bug fixes and cleanup since 2010.
> 
> OK?
>   Ingo
> 
> P.S.
> Note that the current "!siz" is fragile; el_gets(3) sets it to -1
> on error.  I'm polishing that while here.
> 
> P.P.S.
> buf = (char *)el_gets(...) is ugly and potentially dangerous, the
> manual page explicitly warns to not do that, but that's a job for
> another day.
> 
> P.P.P.S.
> Insects are the most successful class of animals on earth.
> Even in OpenBSD, it is rarely possible to look at code without
> finding something unrelated that could be improved, too.

Maybe I've used cdio once or twice and I don't have a cd-player at hand
(at least connected to my workstation) to test this. So purely from code
inspection: You set the signal handler before entering el_gets and you
ignore it right after.

Wouldn't this imply that if you do something like "cdplay" at the prompt
and while you wait for the cd to spin you hit ^C the application just
exits? If so, wouldn't it make more sense to install the signal handler
once and let open_cd() handle EINTR as well and just return to the prompt?

Something that springs to is
cdio> play
<waiting for spinup><wait, wrong command>^C
cdio> cdplay
<playing your favourite tunes>
> 
> 
> Index: cdio.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/cdio/cdio.c,v
> retrieving revision 1.80
> diff -u -p -r1.80 cdio.c
> --- cdio.c      18 Jan 2021 00:44:00 -0000      1.80
> +++ cdio.c      12 Aug 2021 13:36:38 -0000
> @@ -63,6 +63,7 @@
>  #include <err.h>
>  #include <errno.h>
>  #include <fcntl.h>
> +#include <signal.h>
>  #include <stdio.h>
>  #include <stdlib.h>
>  #include <string.h>
> @@ -158,6 +159,7 @@ int         verbose = 1;
>  int            msf = 1;
>  const char     *cddb_host;
>  char           **track_names;
> +volatile sig_atomic_t signo;
>  
>  EditLine       *el = NULL;     /* line-editing structure */
>  History                *hist = NULL;   /* line-editing history */
> @@ -179,6 +181,7 @@ int         pstatus(char *arg);
>  int            play_next(char *arg);
>  int            play_prev(char *arg);
>  int            play_same(char *arg);
> +void           sigint_handler(int);
>  char           *input(int *);
>  char           *prompt(void);
>  void           prtrack(struct cd_toc_entry *e, int lastflag, char *name);
> @@ -1499,18 +1502,36 @@ status(int *trk, int *min, int *sec, int
>         return s.data->header.audio_status;
>  }
>  
> +void
> +sigint_handler(int signo_arg)
> +{
> +       signo = signo_arg;
> +}
> +
>  char *
>  input(int *cmd)
>  {
> +       struct sigaction sa;
>         char *buf;
>         int siz = 0;
>         char *p;
>         HistEvent hev;
>  
> +       memset(&sa, 0, sizeof(sa));
>         do {
> -               if ((buf = (char *) el_gets(el, &siz)) == NULL || !siz) {
> -                       *cmd = CMD_QUIT;
> +               signo = 0;
> +               sa.sa_handler = sigint_handler;
> +               if (sigaction(SIGINT, &sa, NULL) == -1)
> +                       err(1, "sigaction");
> +               buf = (char *)el_gets(el, &siz);
> +               sa.sa_handler = SIG_DFL;
> +               if (sigaction(SIGINT, &sa, NULL) == -1)
> +                       err(1, "sigaction");
> +               if (buf == NULL || siz <= 0) {
>                         fprintf(stderr, "\r\n");
> +                       if (siz < 0 && errno == EINTR && signo == SIGINT)
> +                               continue;
> +                       *cmd = CMD_QUIT;
>                         return (0);
>                 }
>                 if (strlen(buf) > 1)
> 


Reply via email to