Package: mpg321
Version: 0.2.11-1.1
Severity: important
Tags: patch

Hi,

since version 0.2.11, mpg321 will no longer run without a controlling
terminal. This is caused by the xterm title setting code that needs a
controlling terminal and quits if it can't find one.

I've marked this bug as important, since the most common usecase for
mpg321 is probably running from music daemons like mpd or moosic. This
bug prevents mpg321 from working with moosic at least, I haven't tested
mpd.

I've attached a patch that fixes this issue. It makes mpg321 not fail
when no controlling terminal was found. Instead, it will simply skip the
terminal title setting with an error message.

This patch adds some comments and cleans up osc_print and renames it to
set_term_title, for extra source code clarity.

Gr.

Matthijs

-- System Information:
Debian Release: squeeze/sid
  APT prefers unstable
  APT policy: (500, 'unstable'), (500, 'stable'), (1, 'experimental')
Architecture: amd64 (x86_64)

Kernel: Linux 2.6.32-rc8 (PREEMPT)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash

Versions of packages mpg321 depends on:
ii  libao2                  0.8.8-5          Cross Platform Audio Output Librar
ii  libc6                   2.10.2-5         Embedded GNU C Library: Shared lib
ii  libid3tag0              0.15.1b-10       ID3 tag reading library from the M
ii  libmad0                 0.15.1b-4        MPEG audio decoder library
ii  zlib1g                  1:1.2.3.4.dfsg-3 compression library - runtime

mpg321 recommends no packages.

mpg321 suggests no packages.

-- no debconf information
Index: mpg321-0.2.11/mpg321.c
===================================================================
--- mpg321-0.2.11.orig/mpg321.c	2010-01-27 11:31:36.000000000 +0100
+++ mpg321-0.2.11/mpg321.c	2010-01-27 12:28:54.000000000 +0100
@@ -56,7 +56,7 @@
 #include <termios.h>
 #include <config.h>
 
-FILE *ctty, *tty_in, *tty_out;
+FILE *ctty = NULL, *tty_in = NULL, *tty_out = NULL;
 int TTY_FILENO;
 
 struct termios tty_ts, tty_ts_orig; /* termios*/
@@ -303,6 +303,7 @@
     {
         printf ("@R MPG123\n");
     }
+    /* Find our controlling terminal, if any. */
     tty_control();    
     /* Play the mpeg files or zip it! */
     while((currentfile = get_next_file(pl, &playbuf)))
@@ -503,7 +504,7 @@
             fprintf(stderr,"Playing MPEG stream from %s ...\n", basen);
             
 			/*Printing xterm title*/
-			osc_print(0,0,basen);
+			set_term_title(basen);
 	    
             free(dirc);
             free(basec);
@@ -571,7 +572,9 @@
     ao_shutdown();
     /*Restoring TTY*/
     set_tty_restore();
-    osc_print(0,0,"Terminal");
+    /* Restore the terminal title */
+    if(!(options.opt & MPG321_QUIET_PLAY))
+        set_term_title("Terminal");
     if (ctty)
     fclose(ctty);
 
@@ -671,14 +674,13 @@
 
 int tty_control()
 {
-    ctty = NULL;
-
     if (!isatty(STDIN_FILENO) || !isatty(STDOUT_FILENO)) {
       /* get controlling terminal */
       char *program_name = "mpg321";
       if ((ctty = fopen((char *)ctty_path(), "r+")) == NULL) {
-	fprintf(stderr, "%s: failed to get controlling terminal\n",program_name );
-        exit(EXIT_FAILURE);
+        /* This is not fatal, we just don't support raw output now
+         * (e.g., setting the xterm title) */
+        return 1;
       }
     }
     if (!isatty(STDIN_FILENO) && ctty) {
@@ -725,9 +727,12 @@
 }
 
 
-/* issue raw escape sequence */
+/* issue raw escape sequence. Can only be called when we have a
+ * controlling tty (e.g., tty_out is set) */
 int raw_print(char *ctlseq)
 {
+   /* tty_out should have been setup by tty_control() if available. */
+   assert(tty_out);
    int c;
    while ((c = *ctlseq++)) {
       if (c == '\\' && *ctlseq) {
@@ -783,14 +788,18 @@
    return 0;
 }
 
-int osc_print(int ps1, int ps2, char* pt)
-{
-
-    if (pt && *pt)
-	snprintf(temp, sizeof(temp), "\033]%d;%s\007", ps1, pt);
-    else
-        snprintf(temp, sizeof(temp), "\033]%d;?\007", ps1);
-   raw_print(temp);
+/* Set the xterm title and icon the the given string. Will probably work
+ * for other terminal emulators as well. Only works when we have a
+ * controlling terminal, does nothing otherwise. */
+int set_term_title(char* title)
+{
+   if (tty_out) {
+      /* See http://www.faqs.org/docs/Linux-mini/Xterm-Title.html#s3 */
+      snprintf(temp, sizeof(temp), "\033]0;%s\007", title);
+      raw_print(temp);
+   } else {
+      fprintf(stderr, "Cannot set terminal title: failed to get controlling terminal\n");
+   }
    return 0;
 }
 

Reply via email to