#1138545 bts: Only open /dev/tty when needed

Package:
devscripts
Source:
devscripts
Description:
scripts to make the life of a Debian Package maintainer easier
Submitter:
Alexandre Detiste
Date:
2026-05-31 16:01:02 UTC
Severity:
normal
Tags:
#1138545#5
Date:
2025-12-24 11:05:32 UTC
From:
To:
Hi,

since recently, my contrab that sometimes invokes "bts"
to fixup bug metadata fails.

I also provided here a minimal reproducer.

Greetings

Alexandre




Minimal:
""""""""

tchet@quieter:~$ bts version
bts version 2.25.32
Copyright (C) 2001-2003 by Joey Hess <joeyh@debian.org>.
Modifications Copyright (C) 2002-2004 by Julian Gilbey <jdg@debian.org>.
Modifications Copyright (C) 2007 by Josh Triplett <josh@freedesktop.org>.
It is licensed under the terms of the GPL, either version 2 of the
License, or (at your option) any later version.

tchet@quieter:~$ systemd-run --user bts version
Running as unit: run-p14088-i14089.service; invocation ID: 3ab85a60c5024867a7d6fc038f722658

tchet@quieter:~$ journalctl --user -u run-p14088-i14089.service
déc 24 11:59:22 quieter systemd[1426]: Started run-p14088-i14089.service - [systemd-run] /usr/bin/bts version.
déc 24 11:59:22 quieter bts[14089]: Use of uninitialized value $ENV{"_"} in pattern match (m//) at /usr/bin/bts line 1085.
déc 24 11:59:22 quieter bts[14089]: Cannot open /dev/tty: No such device or address at /usr/bin/bts line 1232.
déc 24 11:59:22 quieter systemd[1426]: run-p14088-i14089.service: Main process exited, code=exited, status=6/NOTCONFIGURED
déc 24 11:59:22 quieter systemd[1426]: run-p14088-i14089.service: Failed with result 'exit-code'.


How I found out origininaly:
""""""""""""""""""""""""""""


cron-tchet-tchet-b98f38362b230cd617a7735d072a6463.service - [Cron] "@hourly bin/removal.py"
     Loaded: loaded (/var/spool/cron/crontabs/tchet; generated)
     Active: inactive (dead) since Sun 2025-12-21 04:01:12 CET; 59ms ago
 Invocation: 7d093e5515964bda8382e40011e7695f
TriggeredBy: ● cron-tchet-tchet-b98f38362b230cd617a7735d072a6463.timer
       Docs: man:systemd-crontab-generator(8)
    Process: 4047 ExecStart=/bin/sh /run/systemd/generator/cron-tchet-tchet-b98f38362b230cd617a7735d072a6463.sh (code=exited, status=0/SUCCESS)
   Main PID: 4047 (code=exited, status=0/SUCCESS)
   Mem peak: 44.6M
        CPU: 440ms
2025-12-21T04:00:06+01:00 quieter systemd[1]: Starting cron-tchet-tchet-b98f38362b230cd617a7735d072a6463.service - [Cron] "@hourly bin/removal.py"...
2025-12-21T04:01:12+01:00 quieter sh[4092]: Use of uninitialized value $ENV{"_"} in pattern match (m//) at /usr/bin/bts line 1085.
2025-12-21T04:01:12+01:00 quieter sh[4092]: Cannot open /dev/tty: No such device or address at /usr/bin/bts line 1232.
2025-12-21T04:01:12+01:00 quieter systemd[1]: cron-tchet-tchet-b98f38362b230cd617a7735d072a6463.service: Deactivated successfully.
2025-12-21T04:01:12+01:00 quieter systemd[1]: Finished cron-tchet-tchet-b98f38362b230cd617a7735d072a6463.service - [Cron] "@hourly bin/removal.py".
2025-12-21T04:01:12+01:00 quieter systemd[1]: cron-tchet-tchet-b98f38362b230cd617a7735d072a6463.service: Triggering OnSuccess= dependencies.


tchet@quieter:~$ cat bin/removal.py
#!/usr/bin/python3

import time
time.sleep(60)

import subprocess

import apt_pkg
import debianbts as bts

apt_pkg.init()
SOURCES = apt_pkg.SourceRecords()

bugs = bts.get_bugs(package='ftp.debian.org')

for bug in bts.get_status(list(bugs)):
    if bug.affects or bug.done:
        continue
    if 'RM' in bug.subject and '/experimental' not in bug.subject:
        package = bug.subject.split(':')[1].strip(' ').split()[0].split(',')[0]
        if SOURCES.lookup(package):
            subprocess.call(['bts', 'affect', str(bug.bug_num), package])
--- /etc/devscripts.conf ---
USCAN_SYMLINK=rename
--- ~/.devscripts --- Not present
#1138545#10
Date:
2025-12-24 16:52:08 UTC
From:
To:
Hi Alexandre,

Thanks for the report!

What an annoying edge-case :-). Essentially: controlling TTY isn't set
here.

An easier reproducer I wrote down when working on this code (with the fix):

    $ setsid -w bts version
    bts: WARN: Could not open /dev/tty despite STDIN being a TTY: No such device or address
    bts: Falling back to using STDIN.
    [...]

I've added a fallback to just use STDIN in this case.

Thanks,
--Daniel

#1138545#15
Date:
2025-12-24 16:52:08 UTC
From:
To:
Hi Alexandre,

Thanks for the report!

What an annoying edge-case :-). Essentially: controlling TTY isn't set
here.

An easier reproducer I wrote down when working on this code (with the fix):

    $ setsid -w bts version
    bts: WARN: Could not open /dev/tty despite STDIN being a TTY: No such device or address
    bts: Falling back to using STDIN.
    [...]

I've added a fallback to just use STDIN in this case.

Thanks,
--Daniel

#1138545#20
Date:
2025-12-24 20:27:18 UTC
From:
To:
Hi,

I think that even STDIN cannot be relied to be always there ...

tchet@quieter:~$ setsid -w bts version < /dev/null
Cannot open /dev/tty: No such device or address at /usr/bin/bts line 1232.

Le mer. 24 déc. 2025 à 17:52, Daniel Gröber <dxld@darkboxed.org> a écrit :

#1138545#25
Date:
2025-12-24 22:01:59 UTC
From:
To:
I haven't actually released the fixed version yet. This was with my local
branch :-).

/dev/null is no problem for dup() the code is using now. The new FD will
simply cause read() to return immediately.
--- bts: Fall back to STDIN when /dev/tty fails to open (Closes: #1123934) diff --git a/scripts/bts.pl b/scripts/bts.pl index a7813726..7576f4b4 100755 --- a/scripts/bts.pl +++ b/scripts/bts.pl @@ -1390,8 +1390,13 @@ $implicit_cmd = 'reply' if $use_mua ? $inside_mua : 0; my $stdin_isatty = isatty(\*STDIN); if ($stdin_isatty) { - open(TTY, "+</dev/tty") or die "Cannot open /dev/tty: $!"; + if (not open(TTY, "+</dev/tty")) { + warn "$progname: WARN: Could not open /dev/tty despite STDIN being a TTY.: $!\n"; + warn "$progname: Falling back to using STDIN.\n"; + goto dup_stdin; + } } else { + dup_stdin: open(TTY, "<&STDIN") or die "Could not dup STDIN: $!"; } # Note: To test /dev/tty failure case use $ setsid -w sh -c './bts.pl reply'
#1138545#30
Date:
2026-05-05 20:55:02 UTC
From:
To:
It would be great if you could release the fixed version, or
at least push the patch to git, so we can install manually.

Also, maybe it shouldn't open the TTY unless one of the interactive
commands like reply are invoked? I'm not sure about Alexandre but
all my cron use of bts only uses the cache subcommand, which isn't.

#1138545#33
Date:
2026-05-31 15:37:09 UTC
From:
To:
Hello,

Bug #1123934 in devscripts reported by you has been fixed in the
Git repository and is awaiting an upload. You can see the commit
message below and you can check the diff of the fix at:

https://salsa.debian.org/debian/devscripts/-/commit/f52c34fb4227ec793fe7611caf20b62425489864
------------------------------------------------------------------------
bts: Fall back to STDIN when /dev/tty fails to open (Closes: #1123934)
------------------------------------------------------------------------

(this message was generated automatically)
-- 
Greetings

https://bugs.debian.org/1123934

#1138545#40
Date:
2026-05-31 15:41:16 UTC
From:
To:
Hi Paul, Alexandre,

I'm pushing the fix into 2.26.10 lmk if it works for you.
  runmailreader(), confirmmail(), getpass() and edit().

However I have to get my local WIP branch under control first, so making a
clone for later :-).

Thanks,
--Daniel