⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 perlipc.1

📁 视频监控网络部分的协议ddns,的模块的实现代码,请大家大胆指正.
💻 1
📖 第 1 页 / 共 5 页
字号:
handle.  Consider:.PP.Vb 3\&    open(FH, "|bogus")  or die "can\*(Aqt fork: $!";\&    print FH "bang\en"   or die "can\*(Aqt write: $!";\&    close FH            or die "can\*(Aqt close: $!";.Ve.PPThat won't blow up until the close, and it will blow up with a \s-1SIGPIPE\s0.To catch it, you could use this:.PP.Vb 4\&    $SIG{PIPE} = \*(AqIGNORE\*(Aq;\&    open(FH, "|bogus")  or die "can\*(Aqt fork: $!";\&    print FH "bang\en"   or die "can\*(Aqt write: $!";\&    close FH            or die "can\*(Aqt close: status=$?";.Ve.Sh "Filehandles".IX Subsection "Filehandles"Both the main process and any child processes it forks share the same\&\s-1STDIN\s0, \s-1STDOUT\s0, and \s-1STDERR\s0 filehandles.  If both processes try to accessthem at once, strange things can happen.  You may also want to closeor reopen the filehandles for the child.  You can get around this byopening your pipe with \fIopen()\fR, but on some systems this means that thechild process cannot outlive the parent..Sh "Background Processes".IX Subsection "Background Processes"You can run a command in the background with:.PP.Vb 1\&    system("cmd &");.Ve.PPThe command's \s-1STDOUT\s0 and \s-1STDERR\s0 (and possibly \s-1STDIN\s0, depending on yourshell) will be the same as the parent's.  You won't need to catch\&\s-1SIGCHLD\s0 because of the double-fork taking place (see below for moredetails)..Sh "Complete Dissociation of Child from Parent".IX Subsection "Complete Dissociation of Child from Parent"In some cases (starting server processes, for instance) you'll want tocompletely dissociate the child process from the parent.  This isoften called daemonization.  A well behaved daemon will also \fIchdir()\fRto the root directory (so it doesn't prevent unmounting the filesystemcontaining the directory from which it was launched) and redirect itsstandard file descriptors from and to \fI/dev/null\fR (so that randomoutput doesn't wind up on the user's terminal)..PP.Vb 1\&    use POSIX \*(Aqsetsid\*(Aq;\&\&    sub daemonize {\&        chdir \*(Aq/\*(Aq               or die "Can\*(Aqt chdir to /: $!";\&        open STDIN, \*(Aq/dev/null\*(Aq or die "Can\*(Aqt read /dev/null: $!";\&        open STDOUT, \*(Aq>/dev/null\*(Aq\&                                or die "Can\*(Aqt write to /dev/null: $!";\&        defined(my $pid = fork) or die "Can\*(Aqt fork: $!";\&        exit if $pid;\&        setsid                  or die "Can\*(Aqt start a new session: $!";\&        open STDERR, \*(Aq>&STDOUT\*(Aq or die "Can\*(Aqt dup stdout: $!";\&    }.Ve.PPThe \fIfork()\fR has to come before the \fIsetsid()\fR to ensure that you aren't aprocess group leader (the \fIsetsid()\fR will fail if you are).  If yoursystem doesn't have the \fIsetsid()\fR function, open \fI/dev/tty\fR and use the\&\f(CW\*(C`TIOCNOTTY\*(C'\fR \fIioctl()\fR on it instead.  See \fItty\fR\|(4) for details..PPNon-Unix users should check their Your_OS::Process module for othersolutions..Sh "Safe Pipe Opens".IX Subsection "Safe Pipe Opens"Another interesting approach to \s-1IPC\s0 is making your single program gomultiprocess and communicate between (or even amongst) yourselves.  The\&\fIopen()\fR function will accept a file argument of either \f(CW"\-|"\fR or \f(CW"|\-"\fRto do a very interesting thing: it forks a child connected to thefilehandle you've opened.  The child is running the same program as theparent.  This is useful for safely opening a file when running under anassumed \s-1UID\s0 or \s-1GID\s0, for example.  If you open a pipe \fIto\fR minus, you canwrite to the filehandle you opened and your kid will find it in his\&\s-1STDIN\s0.  If you open a pipe \fIfrom\fR minus, you can read from the filehandleyou opened whatever your kid writes to his \s-1STDOUT\s0..PP.Vb 2\&    use English \*(Aq\-no_match_vars\*(Aq;\&    my $sleep_count = 0;\&\&    do {\&        $pid = open(KID_TO_WRITE, "|\-");\&        unless (defined $pid) {\&            warn "cannot fork: $!";\&            die "bailing out" if $sleep_count++ > 6;\&            sleep 10;\&        }\&    } until defined $pid;\&\&    if ($pid) {  # parent\&        print KID_TO_WRITE @some_data;\&        close(KID_TO_WRITE) || warn "kid exited $?";\&    } else {     # child\&        ($EUID, $EGID) = ($UID, $GID); # suid progs only\&        open (FILE, "> /safe/file")\&            || die "can\*(Aqt open /safe/file: $!";\&        while (<STDIN>) {\&            print FILE; # child\*(Aqs STDIN is parent\*(Aqs KID\&        }\&        exit;  # don\*(Aqt forget this\&    }.Ve.PPAnother common use for this construct is when you need to executesomething without the shell's interference.  With \fIsystem()\fR, it'sstraightforward, but you can't use a pipe open or backticks safely.That's because there's no way to stop the shell from getting its hands onyour arguments.   Instead, use lower-level control to call \fIexec()\fR directly..PPHere's a safe backtick or pipe open for read:.PP.Vb 2\&    # add error processing as above\&    $pid = open(KID_TO_READ, "\-|");\&\&    if ($pid) {   # parent\&        while (<KID_TO_READ>) {\&            # do something interesting\&        }\&        close(KID_TO_READ) || warn "kid exited $?";\&\&    } else {      # child\&        ($EUID, $EGID) = ($UID, $GID); # suid only\&        exec($program, @options, @args)\&            || die "can\*(Aqt exec program: $!";\&        # NOTREACHED\&    }.Ve.PPAnd here's a safe pipe open for writing:.PP.Vb 3\&    # add error processing as above\&    $pid = open(KID_TO_WRITE, "|\-");\&    $SIG{PIPE} = sub { die "whoops, $program pipe broke" };\&\&    if ($pid) {  # parent\&        for (@data) {\&            print KID_TO_WRITE;\&        }\&        close(KID_TO_WRITE) || warn "kid exited $?";\&\&    } else {     # child\&        ($EUID, $EGID) = ($UID, $GID);\&        exec($program, @options, @args)\&            || die "can\*(Aqt exec program: $!";\&        # NOTREACHED\&    }.Ve.PPSince Perl 5.8.0, you can also use the list form of \f(CW\*(C`open\*(C'\fR for pipes :the syntax.PP.Vb 1\&    open KID_PS, "\-|", "ps", "aux" or die $!;.Ve.PPforks the \fIps\fR\|(1) command (without spawning a shell, as there are more thanthree arguments to \fIopen()\fR), and reads its standard output via the\&\f(CW\*(C`KID_PS\*(C'\fR filehandle.  The corresponding syntax to write to commandpipes (with \f(CW"|\-"\fR in place of \f(CW"\-|"\fR) is also implemented..PPNote that these operations are full Unix forks, which means they may not becorrectly implemented on alien systems.  Additionally, these are not truemultithreading.  If you'd like to learn more about threading, see the\&\fImodules\fR file mentioned below in the \s-1SEE\s0 \s-1ALSO\s0 section..Sh "Bidirectional Communication with Another Process".IX Subsection "Bidirectional Communication with Another Process"While this works reasonably well for unidirectional communication, whatabout bidirectional communication?  The obvious thing you'd like to dodoesn't actually work:.PP.Vb 1\&    open(PROG_FOR_READING_AND_WRITING, "| some program |").Ve.PPand if you forget to use the \f(CW\*(C`use warnings\*(C'\fR pragma or the \fB\-w\fR flag,then you'll miss out entirely on the diagnostic message:.PP.Vb 1\&    Can\*(Aqt do bidirectional pipe at \-e line 1..Ve.PPIf you really want to, you can use the standard \fIopen2()\fR library functionto catch both ends.  There's also an \fIopen3()\fR for tridirectional I/O so youcan also catch your child's \s-1STDERR\s0, but doing so would then require anawkward \fIselect()\fR loop and wouldn't allow you to use normal Perl inputoperations..PPIf you look at its source, you'll see that \fIopen2()\fR uses low-levelprimitives like Unix \fIpipe()\fR and \fIexec()\fR calls to create all the connections.While it might have been slightly more efficient by using \fIsocketpair()\fR, itwould have then been even less portable than it already is.  The \fIopen2()\fRand \fIopen3()\fR functions are  unlikely to work anywhere except on a Unixsystem or some other one purporting to be \s-1POSIX\s0 compliant..PPHere's an example of using \fIopen2()\fR:.PP.Vb 5\&    use FileHandle;\&    use IPC::Open2;\&    $pid = open2(*Reader, *Writer, "cat \-u \-n" );\&    print Writer "stuff\en";\&    $got = <Reader>;.Ve.PPThe problem with this is that Unix buffering is really going toruin your day.  Even though your \f(CW\*(C`Writer\*(C'\fR filehandle is auto-flushed,and the process on the other end will get your data in a timely manner,you can't usually do anything to force it to give it back to youin a similarly quick fashion.  In this case, we could, because wegave \fIcat\fR a \fB\-u\fR flag to make it unbuffered.  But very few Unixcommands are designed to operate over pipes, so this seldom worksunless you yourself wrote the program on the other end of thedouble-ended pipe..PPA solution to this is the nonstandard \fIComm.pl\fR library.  It usespseudo-ttys to make your program behave more reasonably:.PP.Vb 6\&    require \*(AqComm.pl\*(Aq;\&    $ph = open_proc(\*(Aqcat \-n\*(Aq);\&    for (1..10) {\&        print $ph "a line\en";\&        print "got back ", scalar <$ph>;\&    }.Ve.PPThis way you don't have to have control over the source code of theprogram you're using.  The \fIComm\fR library also has \fIexpect()\fRand \fIinteract()\fR functions.  Find the library (and we hope itssuccessor \fIIPC::Chat\fR) at your nearest \s-1CPAN\s0 archive as detailedin the \s-1SEE\s0 \s-1ALSO\s0 section below..PPThe newer Expect.pm module from \s-1CPAN\s0 also addresses this kind of thing.This module requires two other modules from \s-1CPAN:\s0 IO::Pty and IO::Stty.It sets up a pseudo-terminal to interact with programs that insist onusing talking to the terminal device driver.  If your system isamongst those supported, this may be your best bet..Sh "Bidirectional Communication with Yourself".IX Subsection "Bidirectional Communication with Yourself"If you want, you may make low-level \fIpipe()\fR and \fIfork()\fRto stitch this together by hand.  This example onlytalks to itself, but you could reopen the appropriatehandles to \s-1STDIN\s0 and \s-1STDOUT\s0 and call other processes..PP.Vb 8\&    #!/usr/bin/perl \-w\&    # pipe1 \- bidirectional communication using two pipe pairs\&    #         designed for the socketpair\-challenged\&    use IO::Handle;     # thousands of lines just for autoflush :\-(\&    pipe(PARENT_RDR, CHILD_WTR);                # XXX: failure?\&    pipe(CHILD_RDR,  PARENT_WTR);               # XXX: failure?\&    CHILD_WTR\->autoflush(1);\&    PARENT_WTR\->autoflush(1);\&\&    if ($pid = fork) {\&        close PARENT_RDR; close PARENT_WTR;\&        print CHILD_WTR "Parent Pid $$ is sending this\en";\&        chomp($line = <CHILD_RDR>);\&        print "Parent Pid $$ just read this: \`$line\*(Aq\en";\&        close CHILD_RDR; close CHILD_WTR;\&        waitpid($pid,0);\&    } else {\&        die "cannot fork: $!" unless defined $pid;\&        close CHILD_RDR; close CHILD_WTR;\&        chomp($line = <PARENT_RDR>);\&        print "Child Pid $$ just read this: \`$line\*(Aq\en";\&        print PARENT_WTR "Child Pid $$ is sending this\en";\&        close PARENT_RDR; close PARENT_WTR;\&        exit;\&    }.Ve.PPBut you don't actually have to make two pipe calls.  If youhave the \fIsocketpair()\fR system call, it will do this all for you..PP.Vb 3\&    #!/usr/bin/perl \-w\&    # pipe2 \- bidirectional communication using socketpair\&    #   "the best ones always go both ways"\&\&    use Socket;\&    use IO::Handle;     # thousands of lines just for autoflush :\-(\&    # We say AF_UNIX because although *_LOCAL is the\&    # POSIX 1003.1g form of the constant, many machines\&    # still don\*(Aqt have it.\&    socketpair(CHILD, PARENT, AF_UNIX, SOCK_STREAM, PF_UNSPEC)\&                                or  die "socketpair: $!";\&\&    CHILD\->autoflush(1);\&    PARENT\->autoflush(1);\&\&    if ($pid = fork) {\&        close PARENT;\&        print CHILD "Parent Pid $$ is sending this\en";\&        chomp($line = <CHILD>);\&        print "Parent Pid $$ just read this: \`$line\*(Aq\en";\&        close CHILD;\&        waitpid($pid,0);\&    } else {\&        die "cannot fork: $!" unless defined $pid;\&        close CHILD;\&        chomp($line = <PARENT>);\&        print "Child Pid $$ just read this: \`$line\*(Aq\en";\&        print PARENT "Child Pid $$ is sending this\en";\&        close PARENT;\&        exit;\&    }.Ve.SH "Sockets: Client/Server Communication".IX Header "Sockets: Client/Server Communication"While not limited to Unix-derived operating systems (e.g., WinSock on PCsprovides socket support, as do some \s-1VMS\s0 libraries), you may not havesockets on your system, in which case this section probably isn't going to doyou much good.  With sockets, you can do both virtual circuits (i.e., \s-1TCP\s0streams) and datagrams (i.e., \s-1UDP\s0 packets).  You may be able to do even moredepending on your system.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -