File: Kde.pm

package info (click to toggle)
debconf 1.5.91
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 5,180 kB
  • sloc: perl: 8,500; sh: 262; python: 182; makefile: 144
file content (138 lines) | stat: -rw-r--r-- 3,607 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
=head1 NAME

Debconf::FrontEnd::Kde - GUI Kde frontend

=cut

package Debconf::FrontEnd::Kde;

use strict;
use warnings;
use IO::Handle;
use Fcntl;
use POSIX ":sys_wait_h";
use Debconf::Config;
use base "Debconf::FrontEnd::Passthrough";

=head1 DESCRIPTION

This frontend is a recommended KDE UI for Debconf. This frontend relays all
requests to the debconf-kde-helper application via Debconf Passthrough
protocol. The latter takes care of displaying actual UI.

By default, debugging output from debconf-kde-helper is silenced.  If you need
to see it, set C<DEBCONF_DEBUG=kde> in the environment.

=cut

=head2 clear_fd_cloexec

Clears FD_CLOEXEC flag for the specified file descriptor

=cut

sub clear_fd_cloexec {
	my $fh = shift;
	my $flags;
	$flags = $fh->fcntl(F_GETFD, 0);
	$flags &= ~FD_CLOEXEC;
	$fh->fcntl(F_SETFD, $flags);
}

=head2 init

This function takes care of starting and preparing debconf-kde-helper for the
communication with Debconf. It opens a pair of FIFO pipes and passes one end to
the debconf-kde-helper process and the other end to the Passthrough frontend.
Before returning, it makes sure that debconf-kde-helper is ready to accept
commands.

=cut

sub init {
	my $this = shift;

	$this->need_tty(0);

	# FIFO pipe for debconf -> helper (dc2hp) communication
	pipe my $dc2hp_readfh, my $dc2hp_writefh;
	# FIFO pipe for helper -> debconf (hp2dc) communication
	pipe my $hp2dc_readfh, my $hp2dc_writefh;

	my $helper_pid = fork();
	if (!defined $helper_pid) {
		die "Unable to fork for execution of debconf-kde-helper: $!\n";
	} elsif ($helper_pid == 0) {
		# Child: execute debconf-kde-helper
		# Close unneeded file handles for this end.
		close $hp2dc_readfh;
		close $dc2hp_writefh;
		# Clear FD_CLOEXEC flags
		clear_fd_cloexec($dc2hp_readfh);
		clear_fd_cloexec($hp2dc_writefh);
		my $debug = Debconf::Config->debug;
		local $ENV{QT_LOGGING_RULES} = 'org.kde.debconf.debug=false'
			unless $debug && 'kde' =~ /$debug/;
		my $fds = sprintf("%d,%d", $dc2hp_readfh->fileno(), $hp2dc_writefh->fileno());
		if (!exec("debconf-kde-helper", "--fifo-fds=$fds")) {
			print STDERR "Unable to execute debconf-kde-helper - is debconf-kde-helper installed?";
			exit(10);
		}
	}

	# Parent process
	# Close unneeded file handles for this end
	close $dc2hp_readfh;
	close $hp2dc_writefh;

	# Initialize Passthrough frontend
	$this->{kde_helper_pid} = $helper_pid;
	$this->{readfh} = $hp2dc_readfh;
	$this->{writefh} = $dc2hp_writefh;
	$this->SUPER::init();

	# Ping debconf-kde-helper and wait for the reply for 15 seconds
	my $timeout = 15;
	my $tag = $this->talk_with_timeout($timeout, "X_PING");
	unless (defined $tag && $tag == 0) {
		close $hp2dc_readfh;
		close $dc2hp_writefh;
		if (waitpid($helper_pid, WNOHANG) == $helper_pid) {
			# debconf-helper-kde has probably died already
			die "debconf-kde-helper terminated abnormally (exit status: " . WEXITSTATUS($?) . ")\n";
		} elsif (kill(0, $helper_pid) == 1) {
			# It has hung or something like that. Kill it forcefully.
			kill 9, $helper_pid;
			# Collect zombie
			waitpid($helper_pid, 0);
		}
		if (defined $tag) {
			die "debconf-kde-helper failed to respond to ping. Response was $tag\n";
		} else {
			die "debconf-kde-helper did not respond to ping in $timeout seconds\n";
		}
	}
}

=head2 shutdown

Closes pipes and waits for the debconf-kde-helper process to finish.

=cut

sub shutdown {
	my $this = shift;
	$this->SUPER::shutdown();
	if (defined $this->{kde_helper_pid}) {
	    waitpid $this->{kde_helper_pid}, 0;
		delete $this->{kde_helper_pid};
	}
}

=head1 AUTHOR

Modestas Vainius <modax@debian.org>

=cut

1;