113498266Sopenharmony_ci#***************************************************************************
213498266Sopenharmony_ci#                                  _   _ ____  _
313498266Sopenharmony_ci#  Project                     ___| | | |  _ \| |
413498266Sopenharmony_ci#                             / __| | | | |_) | |
513498266Sopenharmony_ci#                            | (__| |_| |  _ <| |___
613498266Sopenharmony_ci#                             \___|\___/|_| \_\_____|
713498266Sopenharmony_ci#
813498266Sopenharmony_ci# Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
913498266Sopenharmony_ci#
1013498266Sopenharmony_ci# This software is licensed as described in the file COPYING, which
1113498266Sopenharmony_ci# you should have received as part of this distribution. The terms
1213498266Sopenharmony_ci# are also available at https://curl.se/docs/copyright.html.
1313498266Sopenharmony_ci#
1413498266Sopenharmony_ci# You may opt to use, copy, modify, merge, publish, distribute and/or sell
1513498266Sopenharmony_ci# copies of the Software, and permit persons to whom the Software is
1613498266Sopenharmony_ci# furnished to do so, under the terms of the COPYING file.
1713498266Sopenharmony_ci#
1813498266Sopenharmony_ci# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
1913498266Sopenharmony_ci# KIND, either express or implied.
2013498266Sopenharmony_ci#
2113498266Sopenharmony_ci# SPDX-License-Identifier: curl
2213498266Sopenharmony_ci#
2313498266Sopenharmony_ci###########################################################################
2413498266Sopenharmony_ci
2513498266Sopenharmony_cipackage processhelp;
2613498266Sopenharmony_ci
2713498266Sopenharmony_ciuse strict;
2813498266Sopenharmony_ciuse warnings;
2913498266Sopenharmony_ci
3013498266Sopenharmony_ciBEGIN {
3113498266Sopenharmony_ci    use base qw(Exporter);
3213498266Sopenharmony_ci
3313498266Sopenharmony_ci    our @EXPORT = qw(
3413498266Sopenharmony_ci        portable_sleep
3513498266Sopenharmony_ci        pidfromfile
3613498266Sopenharmony_ci        pidexists
3713498266Sopenharmony_ci        pidwait
3813498266Sopenharmony_ci        processexists
3913498266Sopenharmony_ci        killpid
4013498266Sopenharmony_ci        killsockfilters
4113498266Sopenharmony_ci        killallsockfilters
4213498266Sopenharmony_ci        set_advisor_read_lock
4313498266Sopenharmony_ci        clear_advisor_read_lock
4413498266Sopenharmony_ci    );
4513498266Sopenharmony_ci
4613498266Sopenharmony_ci    # portable sleeping needs Time::HiRes
4713498266Sopenharmony_ci    eval {
4813498266Sopenharmony_ci        no warnings "all";
4913498266Sopenharmony_ci        require Time::HiRes;
5013498266Sopenharmony_ci    };
5113498266Sopenharmony_ci    # portable sleeping falls back to native Sleep on Win32
5213498266Sopenharmony_ci    eval {
5313498266Sopenharmony_ci        no warnings "all";
5413498266Sopenharmony_ci        require Win32;
5513498266Sopenharmony_ci    }
5613498266Sopenharmony_ci}
5713498266Sopenharmony_ci
5813498266Sopenharmony_ciuse serverhelp qw(
5913498266Sopenharmony_ci    servername_id
6013498266Sopenharmony_ci    mainsockf_pidfilename
6113498266Sopenharmony_ci    datasockf_pidfilename
6213498266Sopenharmony_ci    );
6313498266Sopenharmony_ci
6413498266Sopenharmony_ciuse pathhelp qw(
6513498266Sopenharmony_ci    os_is_win
6613498266Sopenharmony_ci    );
6713498266Sopenharmony_ci
6813498266Sopenharmony_ci#######################################################################
6913498266Sopenharmony_ci# portable_sleep uses Time::HiRes::sleep if available and falls back
7013498266Sopenharmony_ci# to the classic approach of using select(undef, undef, undef, ...).
7113498266Sopenharmony_ci# even though that one is not portable due to being implemented using
7213498266Sopenharmony_ci# select on Windows: https://perldoc.perl.org/perlport.html#select
7313498266Sopenharmony_ci# Therefore it uses Win32::Sleep on Windows systems instead.
7413498266Sopenharmony_ci#
7513498266Sopenharmony_cisub portable_sleep {
7613498266Sopenharmony_ci    my ($seconds) = @_;
7713498266Sopenharmony_ci
7813498266Sopenharmony_ci    if($Time::HiRes::VERSION) {
7913498266Sopenharmony_ci        Time::HiRes::sleep($seconds);
8013498266Sopenharmony_ci    }
8113498266Sopenharmony_ci    elsif (os_is_win()) {
8213498266Sopenharmony_ci        Win32::Sleep($seconds*1000);
8313498266Sopenharmony_ci    }
8413498266Sopenharmony_ci    else {
8513498266Sopenharmony_ci        select(undef, undef, undef, $seconds);
8613498266Sopenharmony_ci    }
8713498266Sopenharmony_ci}
8813498266Sopenharmony_ci
8913498266Sopenharmony_ci#######################################################################
9013498266Sopenharmony_ci# pidfromfile returns the pid stored in the given pidfile.  The value
9113498266Sopenharmony_ci# of the returned pid will never be a negative value. It will be zero
9213498266Sopenharmony_ci# on any file related error or if a pid can not be extracted from the
9313498266Sopenharmony_ci# given file.
9413498266Sopenharmony_ci#
9513498266Sopenharmony_cisub pidfromfile {
9613498266Sopenharmony_ci    my $pidfile = $_[0];
9713498266Sopenharmony_ci    my $pid = 0;
9813498266Sopenharmony_ci
9913498266Sopenharmony_ci    if(-f $pidfile && -s $pidfile && open(my $pidfh, "<", "$pidfile")) {
10013498266Sopenharmony_ci        $pid = 0 + <$pidfh>;
10113498266Sopenharmony_ci        close($pidfh);
10213498266Sopenharmony_ci        $pid = 0 if($pid < 0);
10313498266Sopenharmony_ci    }
10413498266Sopenharmony_ci    return $pid;
10513498266Sopenharmony_ci}
10613498266Sopenharmony_ci
10713498266Sopenharmony_ci#######################################################################
10813498266Sopenharmony_ci# pidexists checks if a process with a given pid exists and is alive.
10913498266Sopenharmony_ci# This will return the positive pid if the process exists and is alive.
11013498266Sopenharmony_ci# This will return the negative pid if the process exists differently.
11113498266Sopenharmony_ci# This will return 0 if the process could not be found.
11213498266Sopenharmony_ci#
11313498266Sopenharmony_cisub pidexists {
11413498266Sopenharmony_ci    my $pid = $_[0];
11513498266Sopenharmony_ci
11613498266Sopenharmony_ci    if($pid > 0) {
11713498266Sopenharmony_ci        # verify if currently existing Windows process
11813498266Sopenharmony_ci        if ($pid > 65536 && os_is_win()) {
11913498266Sopenharmony_ci            $pid -= 65536;
12013498266Sopenharmony_ci            if($^O ne 'MSWin32') {
12113498266Sopenharmony_ci                my $filter = "PID eq $pid";
12213498266Sopenharmony_ci                my $result = `tasklist -fi \"$filter\" 2>nul`;
12313498266Sopenharmony_ci                if(index($result, "$pid") != -1) {
12413498266Sopenharmony_ci                    return -$pid;
12513498266Sopenharmony_ci                }
12613498266Sopenharmony_ci                return 0;
12713498266Sopenharmony_ci            }
12813498266Sopenharmony_ci        }
12913498266Sopenharmony_ci
13013498266Sopenharmony_ci        # verify if currently existing and alive
13113498266Sopenharmony_ci        if(kill(0, $pid)) {
13213498266Sopenharmony_ci            return $pid;
13313498266Sopenharmony_ci        }
13413498266Sopenharmony_ci    }
13513498266Sopenharmony_ci
13613498266Sopenharmony_ci    return 0;
13713498266Sopenharmony_ci}
13813498266Sopenharmony_ci
13913498266Sopenharmony_ci#######################################################################
14013498266Sopenharmony_ci# pidterm asks the process with a given pid to terminate gracefully.
14113498266Sopenharmony_ci#
14213498266Sopenharmony_cisub pidterm {
14313498266Sopenharmony_ci    my $pid = $_[0];
14413498266Sopenharmony_ci
14513498266Sopenharmony_ci    if($pid > 0) {
14613498266Sopenharmony_ci        # request the process to quit
14713498266Sopenharmony_ci        if ($pid > 65536 && os_is_win()) {
14813498266Sopenharmony_ci            $pid -= 65536;
14913498266Sopenharmony_ci            if($^O ne 'MSWin32') {
15013498266Sopenharmony_ci                my $filter = "PID eq $pid";
15113498266Sopenharmony_ci                my $result = `tasklist -fi \"$filter\" 2>nul`;
15213498266Sopenharmony_ci                if(index($result, "$pid") != -1) {
15313498266Sopenharmony_ci                    system("taskkill -fi \"$filter\" >nul 2>&1");
15413498266Sopenharmony_ci                }
15513498266Sopenharmony_ci                return;
15613498266Sopenharmony_ci            }
15713498266Sopenharmony_ci        }
15813498266Sopenharmony_ci
15913498266Sopenharmony_ci        # signal the process to terminate
16013498266Sopenharmony_ci        kill("TERM", $pid);
16113498266Sopenharmony_ci    }
16213498266Sopenharmony_ci}
16313498266Sopenharmony_ci
16413498266Sopenharmony_ci#######################################################################
16513498266Sopenharmony_ci# pidkill kills the process with a given pid mercilessly and forcefully.
16613498266Sopenharmony_ci#
16713498266Sopenharmony_cisub pidkill {
16813498266Sopenharmony_ci    my $pid = $_[0];
16913498266Sopenharmony_ci
17013498266Sopenharmony_ci    if($pid > 0) {
17113498266Sopenharmony_ci        # request the process to quit
17213498266Sopenharmony_ci        if ($pid > 65536 && os_is_win()) {
17313498266Sopenharmony_ci            $pid -= 65536;
17413498266Sopenharmony_ci            if($^O ne 'MSWin32') {
17513498266Sopenharmony_ci                my $filter = "PID eq $pid";
17613498266Sopenharmony_ci                my $result = `tasklist -fi \"$filter\" 2>nul`;
17713498266Sopenharmony_ci                if(index($result, "$pid") != -1) {
17813498266Sopenharmony_ci                    system("taskkill -f -fi \"$filter\" >nul 2>&1");
17913498266Sopenharmony_ci                    # Windows XP Home compatibility
18013498266Sopenharmony_ci                    system("tskill $pid >nul 2>&1");
18113498266Sopenharmony_ci                }
18213498266Sopenharmony_ci                return;
18313498266Sopenharmony_ci            }
18413498266Sopenharmony_ci        }
18513498266Sopenharmony_ci
18613498266Sopenharmony_ci        # signal the process to terminate
18713498266Sopenharmony_ci        kill("KILL", $pid);
18813498266Sopenharmony_ci    }
18913498266Sopenharmony_ci}
19013498266Sopenharmony_ci
19113498266Sopenharmony_ci#######################################################################
19213498266Sopenharmony_ci# pidwait waits for the process with a given pid to be terminated.
19313498266Sopenharmony_ci#
19413498266Sopenharmony_cisub pidwait {
19513498266Sopenharmony_ci    my $pid = $_[0];
19613498266Sopenharmony_ci    my $flags = $_[1];
19713498266Sopenharmony_ci
19813498266Sopenharmony_ci    # check if the process exists
19913498266Sopenharmony_ci    if ($pid > 65536 && os_is_win()) {
20013498266Sopenharmony_ci        if($flags == &WNOHANG) {
20113498266Sopenharmony_ci            return pidexists($pid)?0:$pid;
20213498266Sopenharmony_ci        }
20313498266Sopenharmony_ci        while(pidexists($pid)) {
20413498266Sopenharmony_ci            portable_sleep(0.01);
20513498266Sopenharmony_ci        }
20613498266Sopenharmony_ci        return $pid;
20713498266Sopenharmony_ci    }
20813498266Sopenharmony_ci
20913498266Sopenharmony_ci    # wait on the process to terminate
21013498266Sopenharmony_ci    return waitpid($pid, $flags);
21113498266Sopenharmony_ci}
21213498266Sopenharmony_ci
21313498266Sopenharmony_ci#######################################################################
21413498266Sopenharmony_ci# processexists checks if a process with the pid stored in the given
21513498266Sopenharmony_ci# pidfile exists and is alive. This will return 0 on any file related
21613498266Sopenharmony_ci# error or if a pid can not be extracted from the given file. When a
21713498266Sopenharmony_ci# process with the same pid as the one extracted from the given file
21813498266Sopenharmony_ci# is currently alive this returns that positive pid. Otherwise, when
21913498266Sopenharmony_ci# the process is not alive, will return the negative value of the pid.
22013498266Sopenharmony_ci#
22113498266Sopenharmony_cisub processexists {
22213498266Sopenharmony_ci    use POSIX ":sys_wait_h";
22313498266Sopenharmony_ci    my $pidfile = $_[0];
22413498266Sopenharmony_ci
22513498266Sopenharmony_ci    # fetch pid from pidfile
22613498266Sopenharmony_ci    my $pid = pidfromfile($pidfile);
22713498266Sopenharmony_ci
22813498266Sopenharmony_ci    if($pid > 0) {
22913498266Sopenharmony_ci        # verify if currently alive
23013498266Sopenharmony_ci        if(pidexists($pid)) {
23113498266Sopenharmony_ci            return $pid;
23213498266Sopenharmony_ci        }
23313498266Sopenharmony_ci        else {
23413498266Sopenharmony_ci            # get rid of the certainly invalid pidfile
23513498266Sopenharmony_ci            unlink($pidfile) if($pid == pidfromfile($pidfile));
23613498266Sopenharmony_ci            # reap its dead children, if not done yet
23713498266Sopenharmony_ci            pidwait($pid, &WNOHANG);
23813498266Sopenharmony_ci            # negative return value means dead process
23913498266Sopenharmony_ci            return -$pid;
24013498266Sopenharmony_ci        }
24113498266Sopenharmony_ci    }
24213498266Sopenharmony_ci    return 0;
24313498266Sopenharmony_ci}
24413498266Sopenharmony_ci
24513498266Sopenharmony_ci#######################################################################
24613498266Sopenharmony_ci# killpid attempts to gracefully stop processes in the given pid list
24713498266Sopenharmony_ci# with a SIGTERM signal and SIGKILLs those which haven't died on time.
24813498266Sopenharmony_ci#
24913498266Sopenharmony_cisub killpid {
25013498266Sopenharmony_ci    my ($verbose, $pidlist) = @_;
25113498266Sopenharmony_ci    use POSIX ":sys_wait_h";
25213498266Sopenharmony_ci    my @requested;
25313498266Sopenharmony_ci    my @signalled;
25413498266Sopenharmony_ci    my @reapchild;
25513498266Sopenharmony_ci
25613498266Sopenharmony_ci    # The 'pidlist' argument is a string of whitespace separated pids.
25713498266Sopenharmony_ci    return if(not defined($pidlist));
25813498266Sopenharmony_ci
25913498266Sopenharmony_ci    # Make 'requested' hold the non-duplicate pids from 'pidlist'.
26013498266Sopenharmony_ci    @requested = split(' ', $pidlist);
26113498266Sopenharmony_ci    return if(not @requested);
26213498266Sopenharmony_ci    if(scalar(@requested) > 2) {
26313498266Sopenharmony_ci        @requested = sort({$a <=> $b} @requested);
26413498266Sopenharmony_ci    }
26513498266Sopenharmony_ci    for(my $i = scalar(@requested) - 2; $i >= 0; $i--) {
26613498266Sopenharmony_ci        if($requested[$i] == $requested[$i+1]) {
26713498266Sopenharmony_ci            splice @requested, $i+1, 1;
26813498266Sopenharmony_ci        }
26913498266Sopenharmony_ci    }
27013498266Sopenharmony_ci
27113498266Sopenharmony_ci    # Send a SIGTERM to processes which are alive to gracefully stop them.
27213498266Sopenharmony_ci    foreach my $tmp (@requested) {
27313498266Sopenharmony_ci        chomp $tmp;
27413498266Sopenharmony_ci        if($tmp =~ /^(\d+)$/) {
27513498266Sopenharmony_ci            my $pid = $1;
27613498266Sopenharmony_ci            if($pid > 0) {
27713498266Sopenharmony_ci                if(pidexists($pid)) {
27813498266Sopenharmony_ci                    print("RUN: Process with pid $pid signalled to die\n")
27913498266Sopenharmony_ci                        if($verbose);
28013498266Sopenharmony_ci                    pidterm($pid);
28113498266Sopenharmony_ci                    push @signalled, $pid;
28213498266Sopenharmony_ci                }
28313498266Sopenharmony_ci                else {
28413498266Sopenharmony_ci                    print("RUN: Process with pid $pid already dead\n")
28513498266Sopenharmony_ci                        if($verbose);
28613498266Sopenharmony_ci                    # if possible reap its dead children
28713498266Sopenharmony_ci                    pidwait($pid, &WNOHANG);
28813498266Sopenharmony_ci                    push @reapchild, $pid;
28913498266Sopenharmony_ci                }
29013498266Sopenharmony_ci            }
29113498266Sopenharmony_ci        }
29213498266Sopenharmony_ci    }
29313498266Sopenharmony_ci
29413498266Sopenharmony_ci    # Allow all signalled processes five seconds to gracefully die.
29513498266Sopenharmony_ci    if(@signalled) {
29613498266Sopenharmony_ci        my $twentieths = 5 * 20;
29713498266Sopenharmony_ci        while($twentieths--) {
29813498266Sopenharmony_ci            for(my $i = scalar(@signalled) - 1; $i >= 0; $i--) {
29913498266Sopenharmony_ci                my $pid = $signalled[$i];
30013498266Sopenharmony_ci                if(!pidexists($pid)) {
30113498266Sopenharmony_ci                    print("RUN: Process with pid $pid gracefully died\n")
30213498266Sopenharmony_ci                        if($verbose);
30313498266Sopenharmony_ci                    splice @signalled, $i, 1;
30413498266Sopenharmony_ci                    # if possible reap its dead children
30513498266Sopenharmony_ci                    pidwait($pid, &WNOHANG);
30613498266Sopenharmony_ci                    push @reapchild, $pid;
30713498266Sopenharmony_ci                }
30813498266Sopenharmony_ci            }
30913498266Sopenharmony_ci            last if(not scalar(@signalled));
31013498266Sopenharmony_ci            portable_sleep(0.05);
31113498266Sopenharmony_ci        }
31213498266Sopenharmony_ci    }
31313498266Sopenharmony_ci
31413498266Sopenharmony_ci    # Mercilessly SIGKILL processes still alive.
31513498266Sopenharmony_ci    if(@signalled) {
31613498266Sopenharmony_ci        foreach my $pid (@signalled) {
31713498266Sopenharmony_ci            if($pid > 0) {
31813498266Sopenharmony_ci                print("RUN: Process with pid $pid forced to die with SIGKILL\n")
31913498266Sopenharmony_ci                    if($verbose);
32013498266Sopenharmony_ci                pidkill($pid);
32113498266Sopenharmony_ci                # if possible reap its dead children
32213498266Sopenharmony_ci                pidwait($pid, &WNOHANG);
32313498266Sopenharmony_ci                push @reapchild, $pid;
32413498266Sopenharmony_ci            }
32513498266Sopenharmony_ci        }
32613498266Sopenharmony_ci    }
32713498266Sopenharmony_ci
32813498266Sopenharmony_ci    # Reap processes dead children for sure.
32913498266Sopenharmony_ci    if(@reapchild) {
33013498266Sopenharmony_ci        foreach my $pid (@reapchild) {
33113498266Sopenharmony_ci            if($pid > 0) {
33213498266Sopenharmony_ci                pidwait($pid, 0);
33313498266Sopenharmony_ci            }
33413498266Sopenharmony_ci        }
33513498266Sopenharmony_ci    }
33613498266Sopenharmony_ci}
33713498266Sopenharmony_ci
33813498266Sopenharmony_ci#######################################################################
33913498266Sopenharmony_ci# killsockfilters kills sockfilter processes for a given server.
34013498266Sopenharmony_ci#
34113498266Sopenharmony_cisub killsockfilters {
34213498266Sopenharmony_ci    my ($piddir, $proto, $ipvnum, $idnum, $verbose, $which) = @_;
34313498266Sopenharmony_ci    my $server;
34413498266Sopenharmony_ci    my $pidfile;
34513498266Sopenharmony_ci    my $pid;
34613498266Sopenharmony_ci
34713498266Sopenharmony_ci    return if($proto !~ /^(ftp|imap|pop3|smtp)$/);
34813498266Sopenharmony_ci
34913498266Sopenharmony_ci    die "unsupported sockfilter: $which"
35013498266Sopenharmony_ci        if($which && ($which !~ /^(main|data)$/));
35113498266Sopenharmony_ci
35213498266Sopenharmony_ci    $server = servername_id($proto, $ipvnum, $idnum) if($verbose);
35313498266Sopenharmony_ci
35413498266Sopenharmony_ci    if(!$which || ($which eq 'main')) {
35513498266Sopenharmony_ci        $pidfile = mainsockf_pidfilename($piddir, $proto, $ipvnum, $idnum);
35613498266Sopenharmony_ci        $pid = processexists($pidfile);
35713498266Sopenharmony_ci        if($pid > 0) {
35813498266Sopenharmony_ci            printf("* kill pid for %s-%s => %d\n", $server,
35913498266Sopenharmony_ci                ($proto eq 'ftp')?'ctrl':'filt', $pid) if($verbose);
36013498266Sopenharmony_ci            pidkill($pid);
36113498266Sopenharmony_ci            pidwait($pid, 0);
36213498266Sopenharmony_ci        }
36313498266Sopenharmony_ci        unlink($pidfile) if(-f $pidfile);
36413498266Sopenharmony_ci    }
36513498266Sopenharmony_ci
36613498266Sopenharmony_ci    return if($proto ne 'ftp');
36713498266Sopenharmony_ci
36813498266Sopenharmony_ci    if(!$which || ($which eq 'data')) {
36913498266Sopenharmony_ci        $pidfile = datasockf_pidfilename($piddir, $proto, $ipvnum, $idnum);
37013498266Sopenharmony_ci        $pid = processexists($pidfile);
37113498266Sopenharmony_ci        if($pid > 0) {
37213498266Sopenharmony_ci            printf("* kill pid for %s-data => %d\n", $server,
37313498266Sopenharmony_ci                $pid) if($verbose);
37413498266Sopenharmony_ci            pidkill($pid);
37513498266Sopenharmony_ci            pidwait($pid, 0);
37613498266Sopenharmony_ci        }
37713498266Sopenharmony_ci        unlink($pidfile) if(-f $pidfile);
37813498266Sopenharmony_ci    }
37913498266Sopenharmony_ci}
38013498266Sopenharmony_ci
38113498266Sopenharmony_ci#######################################################################
38213498266Sopenharmony_ci# killallsockfilters kills sockfilter processes for all servers.
38313498266Sopenharmony_ci#
38413498266Sopenharmony_cisub killallsockfilters {
38513498266Sopenharmony_ci    my ($piddir, $verbose) = @_;
38613498266Sopenharmony_ci
38713498266Sopenharmony_ci    for my $proto (('ftp', 'imap', 'pop3', 'smtp')) {
38813498266Sopenharmony_ci        for my $ipvnum (('4', '6')) {
38913498266Sopenharmony_ci            for my $idnum (('1', '2')) {
39013498266Sopenharmony_ci                killsockfilters($piddir, $proto, $ipvnum, $idnum, $verbose);
39113498266Sopenharmony_ci            }
39213498266Sopenharmony_ci        }
39313498266Sopenharmony_ci    }
39413498266Sopenharmony_ci}
39513498266Sopenharmony_ci
39613498266Sopenharmony_ci
39713498266Sopenharmony_cisub set_advisor_read_lock {
39813498266Sopenharmony_ci    my ($filename) = @_;
39913498266Sopenharmony_ci
40013498266Sopenharmony_ci    my $fileh;
40113498266Sopenharmony_ci    if(open($fileh, ">", "$filename") && close($fileh)) {
40213498266Sopenharmony_ci        return;
40313498266Sopenharmony_ci    }
40413498266Sopenharmony_ci    printf "Error creating lock file $filename error: $!\n";
40513498266Sopenharmony_ci}
40613498266Sopenharmony_ci
40713498266Sopenharmony_ci
40813498266Sopenharmony_cisub clear_advisor_read_lock {
40913498266Sopenharmony_ci    my ($filename) = @_;
41013498266Sopenharmony_ci
41113498266Sopenharmony_ci    if(-f $filename) {
41213498266Sopenharmony_ci        unlink($filename);
41313498266Sopenharmony_ci    }
41413498266Sopenharmony_ci}
41513498266Sopenharmony_ci
41613498266Sopenharmony_ci
41713498266Sopenharmony_ci1;
418