{
    "content": [
        {
            "type": "text",
            "text": "# IPC::Open2 (perldoc)\n\n## NAME\n\nIPC::Open2 - open a process for both reading and writing using open2()\n\n## SYNOPSIS\n\nuse IPC::Open2;\nmy $pid = open2(my $chldout, my $chldin,\n'some', 'cmd', 'and', 'args');\n# or passing the command through the shell\nmy $pid = open2(my $chldout, my $chldin, 'some cmd and args');\n# read from parent STDIN and write to already open handle\nopen my $outfile, '>', 'outfile.txt' or die \"open failed: $!\";\nmy $pid = open2($outfile, '<&STDIN', 'some', 'cmd', 'and', 'args');\n# read from already open handle and write to parent STDOUT\nopen my $infile, '<', 'infile.txt' or die \"open failed: $!\";\nmy $pid = open2('>&STDOUT', $infile, 'some', 'cmd', 'and', 'args');\n# reap zombie and retrieve exit status\nwaitpid( $pid, 0 );\nmy $childexitstatus = $? >> 8;\n\n## DESCRIPTION\n\nThe open2() function runs the given command and connects $chldout for reading and $chldin for\nwriting. It's what you think should work when you try\n\n## Sections\n\n- **NAME**\n- **SYNOPSIS**\n- **DESCRIPTION** (2 subsections)\n- **WARNING**\n- **SEE ALSO**\n\nUse structuredContent.sections for detailed options, examples, and full documentation.\n"
        }
    ],
    "structuredContent": {
        "command": "IPC::Open2",
        "section": "",
        "mode": "perldoc",
        "summary": "IPC::Open2 - open a process for both reading and writing using open2()",
        "synopsis": "use IPC::Open2;\nmy $pid = open2(my $chldout, my $chldin,\n'some', 'cmd', 'and', 'args');\n# or passing the command through the shell\nmy $pid = open2(my $chldout, my $chldin, 'some cmd and args');\n# read from parent STDIN and write to already open handle\nopen my $outfile, '>', 'outfile.txt' or die \"open failed: $!\";\nmy $pid = open2($outfile, '<&STDIN', 'some', 'cmd', 'and', 'args');\n# read from already open handle and write to parent STDOUT\nopen my $infile, '<', 'infile.txt' or die \"open failed: $!\";\nmy $pid = open2('>&STDOUT', $infile, 'some', 'cmd', 'and', 'args');\n# reap zombie and retrieve exit status\nwaitpid( $pid, 0 );\nmy $childexitstatus = $? >> 8;",
        "tldr_summary": null,
        "tldr_examples": [],
        "tldr_source": null,
        "flags": [],
        "examples": [],
        "see_also": [],
        "section_outline": [
            {
                "name": "NAME",
                "lines": 2,
                "subsections": []
            },
            {
                "name": "SYNOPSIS",
                "lines": 19,
                "subsections": []
            },
            {
                "name": "DESCRIPTION",
                "lines": 16,
                "subsections": [
                    {
                        "name": "open2",
                        "lines": 3
                    },
                    {
                        "name": "open2",
                        "lines": 18
                    }
                ]
            },
            {
                "name": "WARNING",
                "lines": 2,
                "subsections": []
            },
            {
                "name": "SEE ALSO",
                "lines": 3,
                "subsections": []
            }
        ],
        "sections": {
            "NAME": {
                "content": "IPC::Open2 - open a process for both reading and writing using open2()\n",
                "subsections": []
            },
            "SYNOPSIS": {
                "content": "use IPC::Open2;\n\nmy $pid = open2(my $chldout, my $chldin,\n'some', 'cmd', 'and', 'args');\n# or passing the command through the shell\nmy $pid = open2(my $chldout, my $chldin, 'some cmd and args');\n\n# read from parent STDIN and write to already open handle\nopen my $outfile, '>', 'outfile.txt' or die \"open failed: $!\";\nmy $pid = open2($outfile, '<&STDIN', 'some', 'cmd', 'and', 'args');\n\n# read from already open handle and write to parent STDOUT\nopen my $infile, '<', 'infile.txt' or die \"open failed: $!\";\nmy $pid = open2('>&STDOUT', $infile, 'some', 'cmd', 'and', 'args');\n\n# reap zombie and retrieve exit status\nwaitpid( $pid, 0 );\nmy $childexitstatus = $? >> 8;\n",
                "subsections": []
            },
            "DESCRIPTION": {
                "content": "The open2() function runs the given command and connects $chldout for reading and $chldin for\nwriting. It's what you think should work when you try\n\nmy $pid = open(my $fh, \"|cmd args|\");\n\nThe $chldin filehandle will have autoflush turned on.\n\nIf $chldout is a string (that is, a bareword filehandle rather than a glob or a reference) and\nit begins with \">&\", then the child will send output directly to that file handle. If $chldin\nis a string that begins with \"<&\", then $chldin will be closed in the parent, and the child\nwill read from it directly. In both cases, there will be a dup(2) instead of a pipe(2) made.\n\nIf either reader or writer is the empty string or undefined, this will be replaced by an\nautogenerated filehandle. If so, you must pass a valid lvalue in the parameter slot so it can be\noverwritten in the caller, or an exception will be raised.\n",
                "subsections": [
                    {
                        "name": "open2",
                        "content": "raises an exception matching \"/^open2:/\". However, \"exec\" failures in the child are not\ndetected. You'll have to trap SIGPIPE yourself.\n"
                    },
                    {
                        "name": "open2",
                        "content": "where it's acceptable to let the operating system take care of this, you need to do this\nyourself. This is normally as simple as calling \"waitpid $pid, 0\" when you're done with the\nprocess. Failing to do this can result in an accumulation of defunct or \"zombie\" processes. See\n\"waitpid\" in perlfunc for more information.\n\nThis whole affair is quite dangerous, as you may block forever. It assumes it's going to talk to\nsomething like bc(1), both writing to it and reading from it. This is presumably safe because\nyou \"know\" that commands like bc(1) will read a line at a time and output a line at a time.\nPrograms like sort(1) that read their entire input stream first, however, are quite apt to cause\ndeadlock.\n\nThe big problem with this approach is that if you don't have control over source code being run\nin the child process, you can't control what it does with pipe buffering. Thus you can't just\nopen a pipe to \"cat -v\" and continually read and write a line from it.\n\nThe IO::Pty and Expect modules from CPAN can help with this, as they provide a real tty (well, a\npseudo-tty, actually), which gets you back to line buffering in the invoked command again.\n"
                    }
                ]
            },
            "WARNING": {
                "content": "The order of arguments differs from that of open3().\n",
                "subsections": []
            },
            "SEE ALSO": {
                "content": "See IPC::Open3 for an alternative that handles STDERR as well. This function is really just a\nwrapper around open3().\n",
                "subsections": []
            }
        }
    }
}