mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-03-13 17:26:34 +00:00
Init reorganization as the Linux fork resets serial port settings
git-svn-id: https://svn.fhem.de/fhem/trunk@814 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
83fd5300bb
commit
7d77a6212a
@ -13,8 +13,10 @@
|
|||||||
- feature: attr may be a regexp (for CUL_IR)
|
- feature: attr may be a regexp (for CUL_IR)
|
||||||
- feature: Homepage moved from koeniglich.de/fhem to fhem.de
|
- feature: Homepage moved from koeniglich.de/fhem to fhem.de
|
||||||
- feature: eventMap attribute
|
- feature: eventMap attribute
|
||||||
|
- feature: 64_ESA2000 added (by STefan/Gerd)
|
||||||
- feature: new modules 66_ECMD.pm and 67_ECMDDevice.pm for ethersex-enabled
|
- feature: new modules 66_ECMD.pm and 67_ECMDDevice.pm for ethersex-enabled
|
||||||
devices and alike.
|
devices and alike.
|
||||||
|
- bugfix: serial port setting on Linux broken if running in the background
|
||||||
|
|
||||||
- 2010-08-15 (5.0)
|
- 2010-08-15 (5.0)
|
||||||
- **NOTE*: The default installation path is changed to satisfy lintian
|
- **NOTE*: The default installation path is changed to satisfy lintian
|
||||||
|
86
fhem/fhem.pl
86
fhem/fhem.pl
@ -81,6 +81,8 @@ sub fhem($);
|
|||||||
sub fhz($);
|
sub fhz($);
|
||||||
sub IsDummy($);
|
sub IsDummy($);
|
||||||
sub IsIgnored($);
|
sub IsIgnored($);
|
||||||
|
sub setGlobalAttrBeforeFork();
|
||||||
|
sub redirectStdinStdErr();
|
||||||
|
|
||||||
sub CommandAttr($$);
|
sub CommandAttr($$);
|
||||||
sub CommandDefaultAttr($$);
|
sub CommandDefaultAttr($$);
|
||||||
@ -159,13 +161,12 @@ my $logopened = 0; # logfile opened or using stdout
|
|||||||
my %client; # Client array
|
my %client; # Client array
|
||||||
my $rcvdquit; # Used for quit handling in init files
|
my $rcvdquit; # Used for quit handling in init files
|
||||||
my $sig_term = 0; # if set to 1, terminate (saving the state)
|
my $sig_term = 0; # if set to 1, terminate (saving the state)
|
||||||
my $modpath_set; # Check if modpath was used, and report if not.
|
|
||||||
my %intAt; # Internal at timer hash.
|
my %intAt; # Internal at timer hash.
|
||||||
my $nextat; # Time when next timer will be triggered.
|
my $nextat; # Time when next timer will be triggered.
|
||||||
my $intAtCnt=0;
|
my $intAtCnt=0;
|
||||||
my %duplicate; # Pool of received msg for multi-fhz/cul setups
|
my %duplicate; # Pool of received msg for multi-fhz/cul setups
|
||||||
my $duplidx=0; # helper for the above pool
|
my $duplidx=0; # helper for the above pool
|
||||||
my $cvsid = '$Id: fhem.pl,v 1.125 2011-01-29 07:38:13 rudolfkoenig Exp $';
|
my $cvsid = '$Id: fhem.pl,v 1.126 2011-01-29 12:07:14 rudolfkoenig Exp $';
|
||||||
my $namedef =
|
my $namedef =
|
||||||
"where <name> is either:\n" .
|
"where <name> is either:\n" .
|
||||||
"- a single device name\n" .
|
"- a single device name\n" .
|
||||||
@ -238,16 +239,6 @@ my $commonAttr = "eventMap";
|
|||||||
Hlp=>"<devspec> <state>,trigger notify command" },
|
Hlp=>"<devspec> <state>,trigger notify command" },
|
||||||
);
|
);
|
||||||
|
|
||||||
# If started as root, and there is a fhem user in the /etc/passwd, su to it
|
|
||||||
if($^O !~ m/Win/ && $< == 0) {
|
|
||||||
my @pw = getpwnam("fhem");
|
|
||||||
if(@pw) {
|
|
||||||
use POSIX qw(setuid);
|
|
||||||
setuid($pw[2]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
###################################################
|
###################################################
|
||||||
# Start the program
|
# Start the program
|
||||||
if(int(@ARGV) != 1 && int(@ARGV) != 2) {
|
if(int(@ARGV) != 1 && int(@ARGV) != 2) {
|
||||||
@ -258,7 +249,14 @@ if(int(@ARGV) != 1 && int(@ARGV) != 2) {
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
doGlobalDef($ARGV[0]);
|
# If started as root, and there is a fhem user in the /etc/passwd, su to it
|
||||||
|
if($^O !~ m/Win/ && $< == 0) {
|
||||||
|
my @pw = getpwnam("fhem");
|
||||||
|
if(@pw) {
|
||||||
|
use POSIX qw(setuid);
|
||||||
|
setuid($pw[2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
###################################################
|
###################################################
|
||||||
# Client code
|
# Client code
|
||||||
@ -277,11 +275,14 @@ if(int(@ARGV) == 2) {
|
|||||||
# End of client code
|
# End of client code
|
||||||
###################################################
|
###################################################
|
||||||
|
|
||||||
|
|
||||||
###################################################
|
###################################################
|
||||||
# Server initialization
|
# Server initialization
|
||||||
my $ret = CommandInclude(undef, $attr{global}{configfile});
|
doGlobalDef($ARGV[0]);
|
||||||
die($ret) if($ret);
|
|
||||||
|
# As newer Linux versions reset serial parameters after fork, we parse the
|
||||||
|
# config file after the fork. Since need some global attr parameters before, we
|
||||||
|
# read them here.
|
||||||
|
setGlobalAttrBeforeFork();
|
||||||
|
|
||||||
if($^O =~ m/Win/ && !$attr{global}{nofork}) {
|
if($^O =~ m/Win/ && !$attr{global}{nofork}) {
|
||||||
Log 1, "Forcing 'attr global nofork' on WINDOWS";
|
Log 1, "Forcing 'attr global nofork' on WINDOWS";
|
||||||
@ -296,13 +297,15 @@ if($attr{global}{logfile} ne "-" && !$attr{global}{nofork}) {
|
|||||||
exit(0) if $pid;
|
exit(0) if $pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
die("No modpath specified in the configfile.\n") if(!$modpath_set);
|
my $ret = CommandInclude(undef, $attr{global}{configfile});
|
||||||
|
die("$ret\n") if($ret);
|
||||||
die("No port specified in the configfile.\n") if(!$server);
|
die("No port specified in the configfile.\n") if(!$server);
|
||||||
|
|
||||||
if($attr{global}{statefile} && -r $attr{global}{statefile}) {
|
if($attr{global}{statefile} && -r $attr{global}{statefile}) {
|
||||||
$ret = CommandInclude(undef, $attr{global}{statefile});
|
$ret = CommandInclude(undef, $attr{global}{statefile});
|
||||||
die($ret) if($ret);
|
die($ret) if($ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
SignalHandling();
|
SignalHandling();
|
||||||
|
|
||||||
my $pfn = $attr{global}{pidfilename};
|
my $pfn = $attr{global}{pidfilename};
|
||||||
@ -311,7 +314,9 @@ if($pfn) {
|
|||||||
print PID $$ . "\n";
|
print PID $$ . "\n";
|
||||||
close(PID);
|
close(PID);
|
||||||
}
|
}
|
||||||
|
|
||||||
$init_done = 1;
|
$init_done = 1;
|
||||||
|
redirectStdinStdErr();
|
||||||
DoTrigger("global", "INITIALIZED");
|
DoTrigger("global", "INITIALIZED");
|
||||||
|
|
||||||
Log 0, "Server started (version $attr{global}{version}, pid $$)";
|
Log 0, "Server started (version $attr{global}{version}, pid $$)";
|
||||||
@ -802,6 +807,8 @@ CommandInclude($$)
|
|||||||
{
|
{
|
||||||
my ($cl, $arg) = @_;
|
my ($cl, $arg) = @_;
|
||||||
my $fh;
|
my $fh;
|
||||||
|
my $ret = undef;
|
||||||
|
|
||||||
if(!open($fh, $arg)) {
|
if(!open($fh, $arg)) {
|
||||||
return "Can't open $arg: $!";
|
return "Can't open $arg: $!";
|
||||||
}
|
}
|
||||||
@ -813,13 +820,14 @@ CommandInclude($$)
|
|||||||
if($l =~ m/^(.*)\\ *$/) { # Multiline commands
|
if($l =~ m/^(.*)\\ *$/) { # Multiline commands
|
||||||
$bigcmd .= "$1\\\n";
|
$bigcmd .= "$1\\\n";
|
||||||
} else {
|
} else {
|
||||||
AnalyzeCommandChain($cl, $bigcmd . $l);
|
my $tret = AnalyzeCommandChain($cl, $bigcmd . $l);
|
||||||
|
$ret = $tret if(!$ret && $tret);
|
||||||
$bigcmd = "";
|
$bigcmd = "";
|
||||||
}
|
}
|
||||||
last if($rcvdquit);
|
last if($rcvdquit);
|
||||||
}
|
}
|
||||||
close($fh);
|
close($fh);
|
||||||
return undef;
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -843,7 +851,20 @@ OpenLogfile($)
|
|||||||
$defs{global}{logfile} = $attr{global}{logfile};
|
$defs{global}{logfile} = $attr{global}{logfile};
|
||||||
|
|
||||||
open(LOG, ">>$currlogfile") || return("Can't open $currlogfile: $!");
|
open(LOG, ">>$currlogfile") || return("Can't open $currlogfile: $!");
|
||||||
|
redirectStdinStdErr() if($init_done);
|
||||||
|
|
||||||
|
}
|
||||||
|
LOG->autoflush(1);
|
||||||
|
$logopened = 1;
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub
|
||||||
|
redirectStdinStdErr()
|
||||||
|
{
|
||||||
# Redirect stdin/stderr
|
# Redirect stdin/stderr
|
||||||
|
my $currlogfile = $attr{global}{logfile};
|
||||||
|
return if($currlogfile eq "-");
|
||||||
|
|
||||||
open STDIN, '</dev/null' or return "Can't read /dev/null: $!";
|
open STDIN, '</dev/null' or return "Can't read /dev/null: $!";
|
||||||
|
|
||||||
@ -854,10 +875,6 @@ OpenLogfile($)
|
|||||||
close(STDOUT);
|
close(STDOUT);
|
||||||
open STDOUT, '>&STDERR' or return "Can't dup stdout: $!";
|
open STDOUT, '>&STDERR' or return "Can't dup stdout: $!";
|
||||||
STDOUT->autoflush(1);
|
STDOUT->autoflush(1);
|
||||||
}
|
|
||||||
LOG->autoflush(1);
|
|
||||||
$logopened = 1;
|
|
||||||
return undef;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1139,7 +1156,7 @@ CommandDefine($$)
|
|||||||
if(!$modules{$m} || !$modules{$m}{DefFn}) {
|
if(!$modules{$m} || !$modules{$m}{DefFn}) {
|
||||||
my @m = grep { $modules{$_}{DefFn} || !$modules{$_}{LOADED} }
|
my @m = grep { $modules{$_}{DefFn} || !$modules{$_}{LOADED} }
|
||||||
sort keys %modules;
|
sort keys %modules;
|
||||||
return "Unknown argument $m, choose one of @m";
|
return "Unknown module $m, choose one of @m";
|
||||||
}
|
}
|
||||||
|
|
||||||
my %hash;
|
my %hash;
|
||||||
@ -1399,7 +1416,7 @@ CommandReload($$)
|
|||||||
my %hash;
|
my %hash;
|
||||||
$param =~ s,/,,g;
|
$param =~ s,/,,g;
|
||||||
$param =~ s,\.pm$,,g;
|
$param =~ s,\.pm$,,g;
|
||||||
my $file = "$modpath_set/$param.pm";
|
my $file = "$attr{global}{modpath}/FHEM/$param.pm";
|
||||||
return "Can't read $file: $!" if(! -r "$file");
|
return "Can't read $file: $!" if(! -r "$file");
|
||||||
|
|
||||||
my $m = $param;
|
my $m = $param;
|
||||||
@ -1532,7 +1549,7 @@ GlobalAttr($$)
|
|||||||
Listen => 10,
|
Listen => 10,
|
||||||
ReuseAddr => 1);
|
ReuseAddr => 1);
|
||||||
if(!$server2) {
|
if(!$server2) {
|
||||||
Log 1, "Can't open server port at $port: $!\n";
|
Log 1, "Can't open server port at $port: $!";
|
||||||
return "$!" if($init_done);
|
return "$!" if($init_done);
|
||||||
die "Can't open server port at $port: $!\n";
|
die "Can't open server port at $port: $!\n";
|
||||||
}
|
}
|
||||||
@ -1558,7 +1575,6 @@ GlobalAttr($$)
|
|||||||
opendir(DH, $modpath) || return "Can't read $modpath: $!";
|
opendir(DH, $modpath) || return "Can't read $modpath: $!";
|
||||||
my $counter = 0;
|
my $counter = 0;
|
||||||
|
|
||||||
$modpath_set = $modpath;
|
|
||||||
foreach my $m (sort readdir(DH)) {
|
foreach my $m (sort readdir(DH)) {
|
||||||
next if($m !~ m/^([0-9][0-9])_(.*)\.pm$/);
|
next if($m !~ m/^([0-9][0-9])_(.*)\.pm$/);
|
||||||
$modules{$2}{ORDER} = $1;
|
$modules{$2}{ORDER} = $1;
|
||||||
@ -1602,7 +1618,7 @@ CommandAttr($$)
|
|||||||
|
|
||||||
my $list = getAllAttr($sdev);
|
my $list = getAllAttr($sdev);
|
||||||
if($a[1] eq "?") {
|
if($a[1] eq "?") {
|
||||||
push @rets, "Unknown argument $a[1], choose one of $list";
|
push @rets, "Unknown attribute $a[1], choose one of $list";
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1902,6 +1918,7 @@ CommandChain($$)
|
|||||||
for(my $n = 0; $n < $retry; $n++) {
|
for(my $n = 0; $n < $retry; $n++) {
|
||||||
Log 1, sprintf("Trying again $cmd (%d out of %d)", $n+1,$retry) if($n>0);
|
Log 1, sprintf("Trying again $cmd (%d out of %d)", $n+1,$retry) if($n>0);
|
||||||
my $ret = AnalyzeCommand(undef, $cmd);
|
my $ret = AnalyzeCommand(undef, $cmd);
|
||||||
|
Log 1, "> $ret";
|
||||||
last if(!$ret || $ret !~ m/Timeout/);
|
last if(!$ret || $ret !~ m/Timeout/);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2447,3 +2464,16 @@ ReplaceEventMap($$)
|
|||||||
}
|
}
|
||||||
return $str;
|
return $str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub
|
||||||
|
setGlobalAttrBeforeFork()
|
||||||
|
{
|
||||||
|
my $f = $attr{global}{configfile};
|
||||||
|
open(FH, $f) || die("Cant open $f: $!\n");
|
||||||
|
while(my $l = <FH>) {
|
||||||
|
chomp($l);
|
||||||
|
next if($l !~ m/^attr +global +([^ ]+) +(.*)$/);
|
||||||
|
$attr{global}{$1} = $2;
|
||||||
|
}
|
||||||
|
close(FH);
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user