3307 lines
320 KiB
HTML
3307 lines
320 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<meta name="generator" content="Asciidoctor 2.0.23">
|
|
<meta name="author" content="Klemens Morgenstern">
|
|
<title>boost.process</title>
|
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700">
|
|
<style>
|
|
/*! Asciidoctor default stylesheet | MIT License | https://asciidoctor.org */
|
|
/* Uncomment the following line when using as a custom stylesheet */
|
|
/* @import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700"; */
|
|
html{font-family:sans-serif;-webkit-text-size-adjust:100%}
|
|
a{background:none}
|
|
a:focus{outline:thin dotted}
|
|
a:active,a:hover{outline:0}
|
|
h1{font-size:2em;margin:.67em 0}
|
|
b,strong{font-weight:bold}
|
|
abbr{font-size:.9em}
|
|
abbr[title]{cursor:help;border-bottom:1px dotted #dddddf;text-decoration:none}
|
|
dfn{font-style:italic}
|
|
hr{height:0}
|
|
mark{background:#ff0;color:#000}
|
|
code,kbd,pre,samp{font-family:monospace;font-size:1em}
|
|
pre{white-space:pre-wrap}
|
|
q{quotes:"\201C" "\201D" "\2018" "\2019"}
|
|
small{font-size:80%}
|
|
sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}
|
|
sup{top:-.5em}
|
|
sub{bottom:-.25em}
|
|
img{border:0}
|
|
svg:not(:root){overflow:hidden}
|
|
figure{margin:0}
|
|
audio,video{display:inline-block}
|
|
audio:not([controls]){display:none;height:0}
|
|
fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}
|
|
legend{border:0;padding:0}
|
|
button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}
|
|
button,input{line-height:normal}
|
|
button,select{text-transform:none}
|
|
button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}
|
|
button[disabled],html input[disabled]{cursor:default}
|
|
input[type=checkbox],input[type=radio]{padding:0}
|
|
button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}
|
|
textarea{overflow:auto;vertical-align:top}
|
|
table{border-collapse:collapse;border-spacing:0}
|
|
*,::before,::after{box-sizing:border-box}
|
|
html,body{font-size:100%}
|
|
body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;line-height:1;position:relative;cursor:auto;-moz-tab-size:4;-o-tab-size:4;tab-size:4;word-wrap:anywhere;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}
|
|
a:hover{cursor:pointer}
|
|
img,object,embed{max-width:100%;height:auto}
|
|
object,embed{height:100%}
|
|
img{-ms-interpolation-mode:bicubic}
|
|
.left{float:left!important}
|
|
.right{float:right!important}
|
|
.text-left{text-align:left!important}
|
|
.text-right{text-align:right!important}
|
|
.text-center{text-align:center!important}
|
|
.text-justify{text-align:justify!important}
|
|
.hide{display:none}
|
|
img,object,svg{display:inline-block;vertical-align:middle}
|
|
textarea{height:auto;min-height:50px}
|
|
select{width:100%}
|
|
.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}
|
|
div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0}
|
|
a{color:#2156a5;text-decoration:underline;line-height:inherit}
|
|
a:hover,a:focus{color:#1d4b8f}
|
|
a img{border:0}
|
|
p{line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}
|
|
p aside{font-size:.875em;line-height:1.35;font-style:italic}
|
|
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em}
|
|
h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0}
|
|
h1{font-size:2.125em}
|
|
h2{font-size:1.6875em}
|
|
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}
|
|
h4,h5{font-size:1.125em}
|
|
h6{font-size:1em}
|
|
hr{border:solid #dddddf;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em}
|
|
em,i{font-style:italic;line-height:inherit}
|
|
strong,b{font-weight:bold;line-height:inherit}
|
|
small{font-size:60%;line-height:inherit}
|
|
code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)}
|
|
ul,ol,dl{line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}
|
|
ul,ol{margin-left:1.5em}
|
|
ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0}
|
|
ul.circle{list-style-type:circle}
|
|
ul.disc{list-style-type:disc}
|
|
ul.square{list-style-type:square}
|
|
ul.circle ul:not([class]),ul.disc ul:not([class]),ul.square ul:not([class]){list-style:inherit}
|
|
ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}
|
|
dl dt{margin-bottom:.3125em;font-weight:bold}
|
|
dl dd{margin-bottom:1.25em}
|
|
blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}
|
|
blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}
|
|
@media screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}
|
|
h1{font-size:2.75em}
|
|
h2{font-size:2.3125em}
|
|
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}
|
|
h4{font-size:1.4375em}}
|
|
table{background:#fff;margin-bottom:1.25em;border:1px solid #dedede;word-wrap:normal}
|
|
table thead,table tfoot{background:#f7f8f7}
|
|
table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left}
|
|
table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}
|
|
table tr.even,table tr.alt{background:#f8f8f7}
|
|
table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{line-height:1.6}
|
|
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}
|
|
h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}
|
|
.center{margin-left:auto;margin-right:auto}
|
|
.stretch{width:100%}
|
|
.clearfix::before,.clearfix::after,.float-group::before,.float-group::after{content:" ";display:table}
|
|
.clearfix::after,.float-group::after{clear:both}
|
|
:not(pre).nobreak{word-wrap:normal}
|
|
:not(pre).nowrap{white-space:nowrap}
|
|
:not(pre).pre-wrap{white-space:pre-wrap}
|
|
:not(pre):not([class^=L])>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background:#f7f7f8;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed}
|
|
pre{color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;line-height:1.45;text-rendering:optimizeSpeed}
|
|
pre code,pre pre{color:inherit;font-size:inherit;line-height:inherit}
|
|
pre>code{display:block}
|
|
pre.nowrap,pre.nowrap pre{white-space:pre;word-wrap:normal}
|
|
em em{font-style:normal}
|
|
strong strong{font-weight:400}
|
|
.keyseq{color:rgba(51,51,51,.8)}
|
|
kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background:#f7f7f7;border:1px solid #ccc;border-radius:3px;box-shadow:0 1px 0 rgba(0,0,0,.2),inset 0 0 0 .1em #fff;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}
|
|
.keyseq kbd:first-child{margin-left:0}
|
|
.keyseq kbd:last-child{margin-right:0}
|
|
.menuseq,.menuref{color:#000}
|
|
.menuseq b:not(.caret),.menuref{font-weight:inherit}
|
|
.menuseq{word-spacing:-.02em}
|
|
.menuseq b.caret{font-size:1.25em;line-height:.8}
|
|
.menuseq i.caret{font-weight:bold;text-align:center;width:.45em}
|
|
b.button::before,b.button::after{position:relative;top:-1px;font-weight:400}
|
|
b.button::before{content:"[";padding:0 3px 0 2px}
|
|
b.button::after{content:"]";padding:0 2px 0 3px}
|
|
p a>code:hover{color:rgba(0,0,0,.9)}
|
|
#header,#content,#footnotes,#footer{width:100%;margin:0 auto;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em}
|
|
#header::before,#header::after,#content::before,#content::after,#footnotes::before,#footnotes::after,#footer::before,#footer::after{content:" ";display:table}
|
|
#header::after,#content::after,#footnotes::after,#footer::after{clear:both}
|
|
#content{margin-top:1.25em}
|
|
#content::before{content:none}
|
|
#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}
|
|
#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #dddddf}
|
|
#header>h1:only-child{border-bottom:1px solid #dddddf;padding-bottom:8px}
|
|
#header .details{border-bottom:1px solid #dddddf;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:flex;flex-flow:row wrap}
|
|
#header .details span:first-child{margin-left:-.125em}
|
|
#header .details span.email a{color:rgba(0,0,0,.85)}
|
|
#header .details br{display:none}
|
|
#header .details br+span::before{content:"\00a0\2013\00a0"}
|
|
#header .details br+span.author::before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)}
|
|
#header .details br+span#revremark::before{content:"\00a0|\00a0"}
|
|
#header #revnumber{text-transform:capitalize}
|
|
#header #revnumber::after{content:"\00a0"}
|
|
#content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #dddddf;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem}
|
|
#toc{border-bottom:1px solid #e7e7e9;padding-bottom:.5em}
|
|
#toc>ul{margin-left:.125em}
|
|
#toc ul.sectlevel0>li>a{font-style:italic}
|
|
#toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}
|
|
#toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none}
|
|
#toc li{line-height:1.3334;margin-top:.3334em}
|
|
#toc a{text-decoration:none}
|
|
#toc a:active{text-decoration:underline}
|
|
#toctitle{color:#7a2518;font-size:1.2em}
|
|
@media screen and (min-width:768px){#toctitle{font-size:1.375em}
|
|
body.toc2{padding-left:15em;padding-right:0}
|
|
body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #dddddf;padding-bottom:8px}
|
|
#toc.toc2{margin-top:0!important;background:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #e7e7e9;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto}
|
|
#toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}
|
|
#toc.toc2>ul{font-size:.9em;margin-bottom:0}
|
|
#toc.toc2 ul ul{margin-left:0;padding-left:1em}
|
|
#toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}
|
|
body.toc2.toc-right{padding-left:0;padding-right:15em}
|
|
body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #e7e7e9;left:auto;right:0}}
|
|
@media screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}
|
|
#toc.toc2{width:20em}
|
|
#toc.toc2 #toctitle{font-size:1.375em}
|
|
#toc.toc2>ul{font-size:.95em}
|
|
#toc.toc2 ul ul{padding-left:1.25em}
|
|
body.toc2.toc-right{padding-left:0;padding-right:20em}}
|
|
#content #toc{border:1px solid #e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;border-radius:4px}
|
|
#content #toc>:first-child{margin-top:0}
|
|
#content #toc>:last-child{margin-bottom:0}
|
|
#footer{max-width:none;background:rgba(0,0,0,.8);padding:1.25em}
|
|
#footer-text{color:hsla(0,0%,100%,.8);line-height:1.44}
|
|
#content{margin-bottom:.625em}
|
|
.sect1{padding-bottom:.625em}
|
|
@media screen and (min-width:768px){#content{margin-bottom:1.25em}
|
|
.sect1{padding-bottom:1.25em}}
|
|
.sect1:last-child{padding-bottom:0}
|
|
.sect1+.sect1{border-top:1px solid #e7e7e9}
|
|
#content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400}
|
|
#content h1>a.anchor::before,h2>a.anchor::before,h3>a.anchor::before,#toctitle>a.anchor::before,.sidebarblock>.content>.title>a.anchor::before,h4>a.anchor::before,h5>a.anchor::before,h6>a.anchor::before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em}
|
|
#content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}
|
|
#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none}
|
|
#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221}
|
|
details,.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}
|
|
details{margin-left:1.25rem}
|
|
details>summary{cursor:pointer;display:block;position:relative;line-height:1.6;margin-bottom:.625rem;outline:none;-webkit-tap-highlight-color:transparent}
|
|
details>summary::-webkit-details-marker{display:none}
|
|
details>summary::before{content:"";border:solid transparent;border-left:solid;border-width:.3em 0 .3em .5em;position:absolute;top:.5em;left:-1.25rem;transform:translateX(15%)}
|
|
details[open]>summary::before{border:solid transparent;border-top:solid;border-width:.5em .3em 0;transform:translateY(15%)}
|
|
details>summary::after{content:"";width:1.25rem;height:1em;position:absolute;top:.3em;left:-1.25rem}
|
|
.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic}
|
|
table.tableblock.fit-content>caption.title{white-space:nowrap;width:0}
|
|
.paragraph.lead>p,#preamble>.sectionbody>[class=paragraph]:first-of-type p{font-size:1.21875em;line-height:1.6;color:rgba(0,0,0,.85)}
|
|
.admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%}
|
|
.admonitionblock>table td.icon{text-align:center;width:80px}
|
|
.admonitionblock>table td.icon img{max-width:none}
|
|
.admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase}
|
|
.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #dddddf;color:rgba(0,0,0,.6);word-wrap:anywhere}
|
|
.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}
|
|
.exampleblock>.content{border:1px solid #e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;border-radius:4px}
|
|
.sidebarblock{border:1px solid #dbdbd6;margin-bottom:1.25em;padding:1.25em;background:#f3f3f2;border-radius:4px}
|
|
.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}
|
|
.exampleblock>.content>:first-child,.sidebarblock>.content>:first-child{margin-top:0}
|
|
.exampleblock>.content>:last-child,.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0}
|
|
.literalblock pre,.listingblock>.content>pre{border-radius:4px;overflow-x:auto;padding:1em;font-size:.8125em}
|
|
@media screen and (min-width:768px){.literalblock pre,.listingblock>.content>pre{font-size:.90625em}}
|
|
@media screen and (min-width:1280px){.literalblock pre,.listingblock>.content>pre{font-size:1em}}
|
|
.literalblock pre,.listingblock>.content>pre:not(.highlight),.listingblock>.content>pre[class=highlight],.listingblock>.content>pre[class^="highlight "]{background:#f7f7f8}
|
|
.literalblock.output pre{color:#f7f7f8;background:rgba(0,0,0,.9)}
|
|
.listingblock>.content{position:relative}
|
|
.listingblock code[data-lang]::before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:inherit;opacity:.5}
|
|
.listingblock:hover code[data-lang]::before{display:block}
|
|
.listingblock.terminal pre .command::before{content:attr(data-prompt);padding-right:.5em;color:inherit;opacity:.5}
|
|
.listingblock.terminal pre .command:not([data-prompt])::before{content:"$"}
|
|
.listingblock pre.highlightjs{padding:0}
|
|
.listingblock pre.highlightjs>code{padding:1em;border-radius:4px}
|
|
.listingblock pre.prettyprint{border-width:0}
|
|
.prettyprint{background:#f7f7f8}
|
|
pre.prettyprint .linenums{line-height:1.45;margin-left:2em}
|
|
pre.prettyprint li{background:none;list-style-type:inherit;padding-left:0}
|
|
pre.prettyprint li code[data-lang]::before{opacity:1}
|
|
pre.prettyprint li:not(:first-child) code[data-lang]::before{display:none}
|
|
table.linenotable{border-collapse:separate;border:0;margin-bottom:0;background:none}
|
|
table.linenotable td[class]{color:inherit;vertical-align:top;padding:0;line-height:inherit;white-space:normal}
|
|
table.linenotable td.code{padding-left:.75em}
|
|
table.linenotable td.linenos,pre.pygments .linenos{border-right:1px solid;opacity:.35;padding-right:.5em;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}
|
|
pre.pygments span.linenos{display:inline-block;margin-right:.75em}
|
|
.quoteblock{margin:0 1em 1.25em 1.5em;display:table}
|
|
.quoteblock:not(.excerpt)>.title{margin-left:-1.5em;margin-bottom:.75em}
|
|
.quoteblock blockquote,.quoteblock p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify}
|
|
.quoteblock blockquote{margin:0;padding:0;border:0}
|
|
.quoteblock blockquote::before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)}
|
|
.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}
|
|
.quoteblock .attribution{margin-top:.75em;margin-right:.5ex;text-align:right}
|
|
.verseblock{margin:0 1em 1.25em}
|
|
.verseblock pre{font-family:"Open Sans","DejaVu Sans",sans-serif;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility}
|
|
.verseblock pre strong{font-weight:400}
|
|
.verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}
|
|
.quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}
|
|
.quoteblock .attribution br,.verseblock .attribution br{display:none}
|
|
.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)}
|
|
.quoteblock.abstract blockquote::before,.quoteblock.excerpt blockquote::before,.quoteblock .quoteblock blockquote::before{display:none}
|
|
.quoteblock.abstract blockquote,.quoteblock.abstract p,.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{line-height:1.6;word-spacing:0}
|
|
.quoteblock.abstract{margin:0 1em 1.25em;display:block}
|
|
.quoteblock.abstract>.title{margin:0 0 .375em;font-size:1.15em;text-align:center}
|
|
.quoteblock.excerpt>blockquote,.quoteblock .quoteblock{padding:0 0 .25em 1em;border-left:.25em solid #dddddf}
|
|
.quoteblock.excerpt,.quoteblock .quoteblock{margin-left:0}
|
|
.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{color:inherit;font-size:1.0625rem}
|
|
.quoteblock.excerpt .attribution,.quoteblock .quoteblock .attribution{color:inherit;font-size:.85rem;text-align:left;margin-right:0}
|
|
p.tableblock:last-child{margin-bottom:0}
|
|
td.tableblock>.content{margin-bottom:1.25em;word-wrap:anywhere}
|
|
td.tableblock>.content>:last-child{margin-bottom:-1.25em}
|
|
table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}
|
|
table.grid-all>*>tr>*{border-width:1px}
|
|
table.grid-cols>*>tr>*{border-width:0 1px}
|
|
table.grid-rows>*>tr>*{border-width:1px 0}
|
|
table.frame-all{border-width:1px}
|
|
table.frame-ends{border-width:1px 0}
|
|
table.frame-sides{border-width:0 1px}
|
|
table.frame-none>colgroup+*>:first-child>*,table.frame-sides>colgroup+*>:first-child>*{border-top-width:0}
|
|
table.frame-none>:last-child>:last-child>*,table.frame-sides>:last-child>:last-child>*{border-bottom-width:0}
|
|
table.frame-none>*>tr>:first-child,table.frame-ends>*>tr>:first-child{border-left-width:0}
|
|
table.frame-none>*>tr>:last-child,table.frame-ends>*>tr>:last-child{border-right-width:0}
|
|
table.stripes-all>*>tr,table.stripes-odd>*>tr:nth-of-type(odd),table.stripes-even>*>tr:nth-of-type(even),table.stripes-hover>*>tr:hover{background:#f8f8f7}
|
|
th.halign-left,td.halign-left{text-align:left}
|
|
th.halign-right,td.halign-right{text-align:right}
|
|
th.halign-center,td.halign-center{text-align:center}
|
|
th.valign-top,td.valign-top{vertical-align:top}
|
|
th.valign-bottom,td.valign-bottom{vertical-align:bottom}
|
|
th.valign-middle,td.valign-middle{vertical-align:middle}
|
|
table thead th,table tfoot th{font-weight:bold}
|
|
tbody tr th{background:#f7f8f7}
|
|
tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold}
|
|
p.tableblock>code:only-child{background:none;padding:0}
|
|
p.tableblock{font-size:1em}
|
|
ol{margin-left:1.75em}
|
|
ul li ol{margin-left:1.5em}
|
|
dl dd{margin-left:1.125em}
|
|
dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}
|
|
li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em}
|
|
ul.checklist,ul.none,ol.none,ul.no-bullet,ol.no-bullet,ol.unnumbered,ul.unstyled,ol.unstyled{list-style-type:none}
|
|
ul.no-bullet,ol.no-bullet,ol.unnumbered{margin-left:.625em}
|
|
ul.unstyled,ol.unstyled{margin-left:0}
|
|
li>p:empty:only-child::before{content:"";display:inline-block}
|
|
ul.checklist>li>p:first-child{margin-left:-1em}
|
|
ul.checklist>li>p:first-child>.fa-square-o:first-child,ul.checklist>li>p:first-child>.fa-check-square-o:first-child{width:1.25em;font-size:.8em;position:relative;bottom:.125em}
|
|
ul.checklist>li>p:first-child>input[type=checkbox]:first-child{margin-right:.25em}
|
|
ul.inline{display:flex;flex-flow:row wrap;list-style:none;margin:0 0 .625em -1.25em}
|
|
ul.inline>li{margin-left:1.25em}
|
|
.unstyled dl dt{font-weight:400;font-style:normal}
|
|
ol.arabic{list-style-type:decimal}
|
|
ol.decimal{list-style-type:decimal-leading-zero}
|
|
ol.loweralpha{list-style-type:lower-alpha}
|
|
ol.upperalpha{list-style-type:upper-alpha}
|
|
ol.lowerroman{list-style-type:lower-roman}
|
|
ol.upperroman{list-style-type:upper-roman}
|
|
ol.lowergreek{list-style-type:lower-greek}
|
|
.hdlist>table,.colist>table{border:0;background:none}
|
|
.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none}
|
|
td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em}
|
|
td.hdlist1{font-weight:bold;padding-bottom:1.25em}
|
|
td.hdlist2{word-wrap:anywhere}
|
|
.literalblock+.colist,.listingblock+.colist{margin-top:-.5em}
|
|
.colist td:not([class]):first-child{padding:.4em .75em 0;line-height:1;vertical-align:top}
|
|
.colist td:not([class]):first-child img{max-width:none}
|
|
.colist td:not([class]):last-child{padding:.25em 0}
|
|
.thumb,.th{line-height:0;display:inline-block;border:4px solid #fff;box-shadow:0 0 0 1px #ddd}
|
|
.imageblock.left{margin:.25em .625em 1.25em 0}
|
|
.imageblock.right{margin:.25em 0 1.25em .625em}
|
|
.imageblock>.title{margin-bottom:0}
|
|
.imageblock.thumb,.imageblock.th{border-width:6px}
|
|
.imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em}
|
|
.image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}
|
|
.image.left{margin-right:.625em}
|
|
.image.right{margin-left:.625em}
|
|
a.image{text-decoration:none;display:inline-block}
|
|
a.image object{pointer-events:none}
|
|
sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}
|
|
sup.footnote a,sup.footnoteref a{text-decoration:none}
|
|
sup.footnote a:active,sup.footnoteref a:active,#footnotes .footnote a:first-of-type:active{text-decoration:underline}
|
|
#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}
|
|
#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em;border-width:1px 0 0}
|
|
#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;margin-bottom:.2em}
|
|
#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none;margin-left:-1.05em}
|
|
#footnotes .footnote:last-of-type{margin-bottom:0}
|
|
#content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}
|
|
div.unbreakable{page-break-inside:avoid}
|
|
.big{font-size:larger}
|
|
.small{font-size:smaller}
|
|
.underline{text-decoration:underline}
|
|
.overline{text-decoration:overline}
|
|
.line-through{text-decoration:line-through}
|
|
.aqua{color:#00bfbf}
|
|
.aqua-background{background:#00fafa}
|
|
.black{color:#000}
|
|
.black-background{background:#000}
|
|
.blue{color:#0000bf}
|
|
.blue-background{background:#0000fa}
|
|
.fuchsia{color:#bf00bf}
|
|
.fuchsia-background{background:#fa00fa}
|
|
.gray{color:#606060}
|
|
.gray-background{background:#7d7d7d}
|
|
.green{color:#006000}
|
|
.green-background{background:#007d00}
|
|
.lime{color:#00bf00}
|
|
.lime-background{background:#00fa00}
|
|
.maroon{color:#600000}
|
|
.maroon-background{background:#7d0000}
|
|
.navy{color:#000060}
|
|
.navy-background{background:#00007d}
|
|
.olive{color:#606000}
|
|
.olive-background{background:#7d7d00}
|
|
.purple{color:#600060}
|
|
.purple-background{background:#7d007d}
|
|
.red{color:#bf0000}
|
|
.red-background{background:#fa0000}
|
|
.silver{color:#909090}
|
|
.silver-background{background:#bcbcbc}
|
|
.teal{color:#006060}
|
|
.teal-background{background:#007d7d}
|
|
.white{color:#bfbfbf}
|
|
.white-background{background:#fafafa}
|
|
.yellow{color:#bfbf00}
|
|
.yellow-background{background:#fafa00}
|
|
span.icon>.fa{cursor:default}
|
|
a span.icon>.fa{cursor:inherit}
|
|
.admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default}
|
|
.admonitionblock td.icon .icon-note::before{content:"\f05a";color:#19407c}
|
|
.admonitionblock td.icon .icon-tip::before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111}
|
|
.admonitionblock td.icon .icon-warning::before{content:"\f071";color:#bf6900}
|
|
.admonitionblock td.icon .icon-caution::before{content:"\f06d";color:#bf3400}
|
|
.admonitionblock td.icon .icon-important::before{content:"\f06a";color:#bf0000}
|
|
.conum[data-value]{display:inline-block;color:#fff!important;background:rgba(0,0,0,.8);border-radius:50%;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold}
|
|
.conum[data-value] *{color:#fff!important}
|
|
.conum[data-value]+b{display:none}
|
|
.conum[data-value]::after{content:attr(data-value)}
|
|
pre .conum[data-value]{position:relative;top:-.125em}
|
|
b.conum *{color:inherit!important}
|
|
.conum:not([data-value]):empty{display:none}
|
|
dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}
|
|
h1,h2,p,td.content,span.alt,summary{letter-spacing:-.01em}
|
|
p strong,td.content strong,div.footnote strong{letter-spacing:-.005em}
|
|
p,blockquote,dt,td.content,td.hdlist1,span.alt,summary{font-size:1.0625rem}
|
|
p{margin-bottom:1.25rem}
|
|
.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}
|
|
.exampleblock>.content{background:#fffef7;border-color:#e0e0dc;box-shadow:0 1px 4px #e0e0dc}
|
|
.print-only{display:none!important}
|
|
@page{margin:1.25cm .75cm}
|
|
@media print{*{box-shadow:none!important;text-shadow:none!important}
|
|
html{font-size:80%}
|
|
a{color:inherit!important;text-decoration:underline!important}
|
|
a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}
|
|
a[href^="http:"]:not(.bare)::after,a[href^="https:"]:not(.bare)::after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}
|
|
abbr[title]{border-bottom:1px dotted}
|
|
abbr[title]::after{content:" (" attr(title) ")"}
|
|
pre,blockquote,tr,img,object,svg{page-break-inside:avoid}
|
|
thead{display:table-header-group}
|
|
svg{max-width:100%}
|
|
p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}
|
|
h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid}
|
|
#header,#content,#footnotes,#footer{max-width:none}
|
|
#toc,.sidebarblock,.exampleblock>.content{background:none!important}
|
|
#toc{border-bottom:1px solid #dddddf!important;padding-bottom:0!important}
|
|
body.book #header{text-align:center}
|
|
body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em}
|
|
body.book #header .details{border:0!important;display:block;padding:0!important}
|
|
body.book #header .details span:first-child{margin-left:0!important}
|
|
body.book #header .details br{display:block}
|
|
body.book #header .details br+span::before{content:none!important}
|
|
body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important}
|
|
body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always}
|
|
.listingblock code[data-lang]::before{display:block}
|
|
#footer{padding:0 .9375em}
|
|
.hide-on-print{display:none!important}
|
|
.print-only{display:block!important}
|
|
.hide-for-print{display:none!important}
|
|
.show-for-print{display:inherit!important}}
|
|
@media amzn-kf8,print{#header>h1:first-child{margin-top:1.25rem}
|
|
.sect1{padding:0!important}
|
|
.sect1+.sect1{border:0}
|
|
#footer{background:none}
|
|
#footer-text{color:rgba(0,0,0,.6);font-size:.9em}}
|
|
@media amzn-kf8{#header,#content,#footnotes,#footer{padding:0}}
|
|
</style>
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
|
<style>
|
|
pre.rouge table td { padding: 5px; }
|
|
pre.rouge table pre { margin: 0; }
|
|
pre.rouge, pre.rouge .w {
|
|
color: #24292f;
|
|
background-color: #f6f8fa;
|
|
}
|
|
pre.rouge .k, pre.rouge .kd, pre.rouge .kn, pre.rouge .kp, pre.rouge .kr, pre.rouge .kt, pre.rouge .kv {
|
|
color: #cf222e;
|
|
}
|
|
pre.rouge .gr {
|
|
color: #f6f8fa;
|
|
}
|
|
pre.rouge .gd {
|
|
color: #82071e;
|
|
background-color: #ffebe9;
|
|
}
|
|
pre.rouge .nb {
|
|
color: #953800;
|
|
}
|
|
pre.rouge .nc {
|
|
color: #953800;
|
|
}
|
|
pre.rouge .no {
|
|
color: #953800;
|
|
}
|
|
pre.rouge .nn {
|
|
color: #953800;
|
|
}
|
|
pre.rouge .sr {
|
|
color: #116329;
|
|
}
|
|
pre.rouge .na {
|
|
color: #116329;
|
|
}
|
|
pre.rouge .nt {
|
|
color: #116329;
|
|
}
|
|
pre.rouge .gi {
|
|
color: #116329;
|
|
background-color: #dafbe1;
|
|
}
|
|
pre.rouge .ges {
|
|
font-weight: bold;
|
|
font-style: italic;
|
|
}
|
|
pre.rouge .kc {
|
|
color: #0550ae;
|
|
}
|
|
pre.rouge .l, pre.rouge .ld, pre.rouge .m, pre.rouge .mb, pre.rouge .mf, pre.rouge .mh, pre.rouge .mi, pre.rouge .il, pre.rouge .mo, pre.rouge .mx {
|
|
color: #0550ae;
|
|
}
|
|
pre.rouge .sb {
|
|
color: #0550ae;
|
|
}
|
|
pre.rouge .bp {
|
|
color: #0550ae;
|
|
}
|
|
pre.rouge .ne {
|
|
color: #0550ae;
|
|
}
|
|
pre.rouge .nl {
|
|
color: #0550ae;
|
|
}
|
|
pre.rouge .py {
|
|
color: #0550ae;
|
|
}
|
|
pre.rouge .nv, pre.rouge .vc, pre.rouge .vg, pre.rouge .vi, pre.rouge .vm {
|
|
color: #0550ae;
|
|
}
|
|
pre.rouge .o, pre.rouge .ow {
|
|
color: #0550ae;
|
|
}
|
|
pre.rouge .gh {
|
|
color: #0550ae;
|
|
font-weight: bold;
|
|
}
|
|
pre.rouge .gu {
|
|
color: #0550ae;
|
|
font-weight: bold;
|
|
}
|
|
pre.rouge .s, pre.rouge .sa, pre.rouge .sc, pre.rouge .dl, pre.rouge .sd, pre.rouge .s2, pre.rouge .se, pre.rouge .sh, pre.rouge .sx, pre.rouge .s1, pre.rouge .ss {
|
|
color: #0a3069;
|
|
}
|
|
pre.rouge .nd {
|
|
color: #8250df;
|
|
}
|
|
pre.rouge .nf, pre.rouge .fm {
|
|
color: #8250df;
|
|
}
|
|
pre.rouge .err {
|
|
color: #f6f8fa;
|
|
background-color: #82071e;
|
|
}
|
|
pre.rouge .c, pre.rouge .ch, pre.rouge .cd, pre.rouge .cm, pre.rouge .cp, pre.rouge .cpf, pre.rouge .c1, pre.rouge .cs {
|
|
color: #6e7781;
|
|
}
|
|
pre.rouge .gl {
|
|
color: #6e7781;
|
|
}
|
|
pre.rouge .gt {
|
|
color: #6e7781;
|
|
}
|
|
pre.rouge .ni {
|
|
color: #24292f;
|
|
}
|
|
pre.rouge .si {
|
|
color: #24292f;
|
|
}
|
|
pre.rouge .ge {
|
|
color: #24292f;
|
|
font-style: italic;
|
|
}
|
|
pre.rouge .gs {
|
|
color: #24292f;
|
|
font-weight: bold;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body class="article toc2 toc-left">
|
|
<div id="header">
|
|
<h1>boost.process</h1>
|
|
<div class="details">
|
|
<span id="author" class="author">Klemens Morgenstern</span><br>
|
|
<span id="email" class="email"><a href="mailto:klemens.morgenstern@gmx.net">klemens.morgenstern@gmx.net</a></span><br>
|
|
<span id="revnumber">version 2.0,</span>
|
|
<span id="revdate">19.11.2024</span>
|
|
</div>
|
|
<div id="toc" class="toc2">
|
|
<div id="toctitle">Table of Contents</div>
|
|
<ul class="sectlevel1">
|
|
<li><a href="#quickstart">Quickstart</a>
|
|
<ul class="sectlevel2">
|
|
<li><a href="#lifetime">Lifetime</a></li>
|
|
<li><a href="#signalling_the_subprocess">Signalling the subprocess</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#launcher">Launcher</a>
|
|
<ul class="sectlevel2">
|
|
<li><a href="#linux_launchers">Linux Launchers</a></li>
|
|
<li><a href="#windows_launchers">Windows Launchers</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#initializers">Initializers</a>
|
|
<ul class="sectlevel2">
|
|
<li><a href="#process_start_dir"><code>process_start_dir</code></a></li>
|
|
<li><a href="#pipes">Pipes</a></li>
|
|
<li><a href="#file"><code>FILE*</code></a></li>
|
|
<li><a href="#nullptr"><code>nullptr</code></a></li>
|
|
<li><a href="#native_handle"><code>native_handle</code></a></li>
|
|
<li><a href="#popen">popen</a></li>
|
|
<li><a href="#environment">Environment</a></li>
|
|
<li><a href="#subprocess_environment">Subprocess environment</a></li>
|
|
<li><a href="#inheriting_an_environment">Inheriting an environment</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#reference">Reference</a>
|
|
<ul class="sectlevel2">
|
|
<li><a href="#bind_launcher_hpp"><code>bind_launcher.hpp</code></a></li>
|
|
<li><a href="#cstring_ref_hpp"><code>cstring_ref.hpp</code></a></li>
|
|
<li><a href="#environment_hpp"><code>environment.hpp</code></a>
|
|
<ul class="sectlevel3">
|
|
<li><a href="#environment"><code>environment</code></a></li>
|
|
<li><a href="#process_environment"><code>process_environment</code></a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#error_hpp"><code>error.hpp</code></a></li>
|
|
<li><a href="#execute_hpp"><code>execute.hpp</code></a></li>
|
|
<li><a href="#exit_code_hpp"><code>exit_code.hpp</code></a></li>
|
|
<li><a href="#ext"><code>ext</code></a></li>
|
|
<li><a href="#pid_hpp"><code>pid.hpp</code></a></li>
|
|
<li><a href="#popen_hpp"><code>popen.hpp</code></a></li>
|
|
<li><a href="#process_hpp"><code>process.hpp</code></a></li>
|
|
<li><a href="#process_handle_hpp"><code>process_handle.hpp</code></a></li>
|
|
<li><a href="#shell_hpp"><code>shell.hpp</code></a></li>
|
|
<li><a href="#start_dir_hpp"><code>start_dir.hpp</code></a></li>
|
|
<li><a href="#stdio_hpp"><code>stdio.hpp</code></a></li>
|
|
<li><a href="#ext_2"><code>ext</code></a></li>
|
|
<li><a href="#posixbind_fd_hpp"><code>posix/bind_fd.hpp</code></a></li>
|
|
<li><a href="#windowscreation_flags_hpp"><code>windows/creation_flags.hpp</code></a></li>
|
|
<li><a href="#windowsshow_window_hpp"><code>windows/show_window.hpp</code></a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#version_2">Version 2</a>
|
|
<ul class="sectlevel2">
|
|
<li><a href="#simplified_interface">Simplified Interface</a></li>
|
|
<li><a href="#pidfd_open"><code>pidfd_open</code></a></li>
|
|
<li><a href="#full_asio_integration">Full asio integration</a></li>
|
|
<li><a href="#unreliable_functionality">Unreliable functionality</a></li>
|
|
<li><a href="#utf_8">UTF-8</a></li>
|
|
<li><a href="#fd_safe_by_default">Fd safe by default</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#acknowledgements">Acknowledgements</a></li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
<div id="content">
|
|
<div class="sect1">
|
|
<h2 id="quickstart">Quickstart</h2>
|
|
<div class="sectionbody">
|
|
<div class="paragraph">
|
|
<p>A process needs four things to be launched:</p>
|
|
</div>
|
|
<div class="ulist">
|
|
<ul>
|
|
<li>
|
|
<p>an asio execution_context / executor</p>
|
|
</li>
|
|
<li>
|
|
<p>a path to an executable</p>
|
|
</li>
|
|
<li>
|
|
<p>a list of arguments</p>
|
|
</li>
|
|
<li>
|
|
<p>a variadic set of initializers</p>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="title">example/quickstart.cpp:13-17</div>
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"><span class="c1">// process(asio::any_io_executor, filesystem::path, range<string> args, AdditionalInitializers...)</span>
|
|
<span class="n">process</span> <span class="nf">proc</span><span class="p">(</span><span class="n">ctx</span><span class="p">.</span><span class="n">get_executor</span><span class="p">(),</span> <i class="conum" data-value="1"></i><b>(1)</b>
|
|
<span class="s">"/usr/bin/cp"</span><span class="p">,</span> <i class="conum" data-value="2"></i><b>(2)</b>
|
|
<span class="p">{</span><span class="s">"source.txt"</span><span class="p">,</span> <span class="s">"target.txt"</span><span class="p">}</span> <i class="conum" data-value="3"></i><b>(3)</b>
|
|
<span class="p">);</span> <i class="conum" data-value="4"></i><b>(4)</b></code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="colist arabic">
|
|
<table>
|
|
<tr>
|
|
<td><i class="conum" data-value="1"></i><b>1</b></td>
|
|
<td>The executor for the process handle</td>
|
|
</tr>
|
|
<tr>
|
|
<td><i class="conum" data-value="2"></i><b>2</b></td>
|
|
<td>The Path to the executable</td>
|
|
</tr>
|
|
<tr>
|
|
<td><i class="conum" data-value="3"></i><b>3</b></td>
|
|
<td>The argument list in the form of an <code>std::initializer_list</code>.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><i class="conum" data-value="4"></i><b>4</b></td>
|
|
<td>Not additional initializers</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The started process can then be awaited or terminated.</p>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="lifetime">Lifetime</h3>
|
|
<div class="paragraph">
|
|
<p>If the process handle goes out of scope, it will terminate the subprocess.
|
|
You can prevent this, by calling <code>proc.detach()</code>; do however note that this
|
|
can lead to zombie processes.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>A process that completed will deliver an exit-code,
|
|
which can be obtained by calling <code>.exit_code</code> on the exited process and which is
|
|
also returned from <code>.wait()</code>.</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="title">example/quickstart.cpp:22-23</div>
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"><span class="n">process</span> <span class="nf">proc</span><span class="p">(</span><span class="n">ctx</span><span class="p">,</span> <span class="s">"/bin/ls"</span><span class="p">,</span> <span class="p">{});</span>
|
|
<span class="n">assert</span><span class="p">(</span><span class="n">proc</span><span class="p">.</span><span class="n">wait</span><span class="p">()</span> <span class="o">==</span> <span class="mi">0</span><span class="p">);</span></code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The normal exit-code is what the subprocess returned from <code>main</code>;
|
|
posix will however add additional information about the process.
|
|
This is called the <code>native_exit_code</code>.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The <code>.running()</code> function can be used to detect if the process is still active.</p>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="signalling_the_subprocess">Signalling the subprocess</h3>
|
|
<div class="paragraph">
|
|
<p>The parent process can signal the subprocess demanding certain actions.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p><code>.terminate</code> will cause the subprocess to exit immediately (<code>SIGKILL</code> on posix).
|
|
This is the only reliable & portable way to end a subprocess.</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="title">example/quickstart.cpp:28-29</div>
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"><span class="n">process</span> <span class="nf">proc</span><span class="p">(</span><span class="n">ctx</span><span class="p">,</span> <span class="s">"/bin/totally-not-a-virus"</span><span class="p">,</span> <span class="p">{});</span>
|
|
<span class="n">proc</span><span class="p">.</span><span class="n">terminate</span><span class="p">();</span></code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p><code>.request_exit</code> will ask the subprocess to shutdown (<code>SIGTERM</code> on posix),
|
|
which the subprocess might ignore.</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="title">example/quickstart.cpp:34-36</div>
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"> <span class="n">process</span> <span class="nf">proc</span><span class="p">(</span><span class="n">ctx</span><span class="p">,</span> <span class="s">"/bin/bash"</span><span class="p">,</span> <span class="p">{});</span>
|
|
<span class="n">proc</span><span class="p">.</span><span class="n">request_exit</span><span class="p">();</span>
|
|
<span class="n">proc</span><span class="p">.</span><span class="n">wait</span><span class="p">();</span></code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p><code>.interrupt</code> will send an SIGINT to the subprocess, which a subprocess might
|
|
interpret as a signal for shutdown.</p>
|
|
</div>
|
|
<div class="admonitionblock warning">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-warning" title="Warning"></i>
|
|
</td>
|
|
<td class="content">
|
|
interrupt requires the initializer <code>windows::create_new_process_group</code> to be set on windows
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="title">example/quickstart.cpp:41-43</div>
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"> <span class="n">process</span> <span class="nf">proc</span><span class="p">(</span><span class="n">ctx</span><span class="p">,</span> <span class="s">"/usr/bin/addr2line"</span><span class="p">,</span> <span class="p">{});</span>
|
|
<span class="n">proc</span><span class="p">.</span><span class="n">interrupt</span><span class="p">();</span>
|
|
<span class="n">proc</span><span class="p">.</span><span class="n">wait</span><span class="p">();</span></code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>Process v2 provides <code>execute</code> and <code>async_execute</code> functions that can be used for managed executions.</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="title">example/quickstart.cpp:48</div>
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"> <span class="n">assert</span><span class="p">(</span><span class="n">execute</span><span class="p">(</span><span class="n">process</span><span class="p">(</span><span class="n">ctx</span><span class="p">,</span> <span class="s">"/bin/ls"</span><span class="p">,</span> <span class="p">{}))</span> <span class="o">==</span> <span class="mi">0</span><span class="p">);</span></code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The async version supports cancellation and will forward cancellation types as follows:</p>
|
|
</div>
|
|
<div class="ulist">
|
|
<ul>
|
|
<li>
|
|
<p><code>asio::cancellation_type::total</code> → interrupt</p>
|
|
</li>
|
|
<li>
|
|
<p><code>asio::cancellation_type::partial</code> → request_exit</p>
|
|
</li>
|
|
<li>
|
|
<p><code>asio::cancellation_type::terminal</code> → terminate</p>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="title">example/quickstart.cpp:53-56</div>
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"> <span class="n">async_execute</span><span class="p">(</span><span class="n">process</span><span class="p">(</span><span class="n">ctx</span><span class="p">,</span> <span class="s">"/usr/bin/g++"</span><span class="p">,</span> <span class="p">{</span><span class="s">"hello_world.cpp"</span><span class="p">}))</span>
|
|
<span class="p">(</span><span class="n">asio</span><span class="o">::</span><span class="n">cancel_after</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">chrono</span><span class="o">::</span><span class="n">seconds</span><span class="p">(</span><span class="mi">10</span><span class="p">),</span> <span class="n">asio</span><span class="o">::</span><span class="n">cancellation_type</span><span class="o">::</span><span class="n">partial</span><span class="p">))</span> <i class="conum" data-value="1"></i><b>(1)</b>
|
|
<span class="p">(</span><span class="n">asio</span><span class="o">::</span><span class="n">cancel_after</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">chrono</span><span class="o">::</span><span class="n">seconds</span><span class="p">(</span><span class="mi">10</span><span class="p">),</span> <span class="n">asio</span><span class="o">::</span><span class="n">cancellation_type</span><span class="o">::</span><span class="n">terminal</span><span class="p">))</span> <i class="conum" data-value="2"></i><b>(2)</b>
|
|
<span class="p">(</span><span class="n">asio</span><span class="o">::</span><span class="n">detached</span><span class="p">);</span></code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="colist arabic">
|
|
<table>
|
|
<tr>
|
|
<td><i class="conum" data-value="1"></i><b>1</b></td>
|
|
<td>After 10 seconds send a request_exit.</td>
|
|
</tr>
|
|
<tr>
|
|
<td><i class="conum" data-value="2"></i><b>2</b></td>
|
|
<td>After 20 seconds terminate</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect1">
|
|
<h2 id="launcher">Launcher</h2>
|
|
<div class="sectionbody">
|
|
<div class="paragraph">
|
|
<p>The process creation is done by a process_launcher.
|
|
The constructor of <code>process</code> will use the default_launcher, which varies by system.
|
|
There are additional launcher available on most systems.</p>
|
|
</div>
|
|
<table class="tableblock frame-all grid-all stretch">
|
|
<colgroup>
|
|
<col style="width: 25%;">
|
|
<col style="width: 25%;">
|
|
<col style="width: 25%;">
|
|
<col style="width: 25%;">
|
|
</colgroup>
|
|
<thead>
|
|
<tr>
|
|
<th class="tableblock halign-left valign-top">Name</th>
|
|
<th class="tableblock halign-left valign-top">Summary</th>
|
|
<th class="tableblock halign-left valign-top">Default on</th>
|
|
<th class="tableblock halign-left valign-top">Available on</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>windows::default_launcher</code></p></td>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CreateProcessW</code></p></td>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">windows</p></td>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">windows</p></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>windows::as_user_launcher</code></p></td>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CreateProcessAsUserW</code></p></td>
|
|
<td class="tableblock halign-left valign-top"></td>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">windows</p></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>windows::with_logon_launcher</code></p></td>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CreateProcessWithLogonW</code></p></td>
|
|
<td class="tableblock halign-left valign-top"></td>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">windows</p></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>windows::with_token_launcher</code></p></td>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CreateProcessWithTokenW</code></p></td>
|
|
<td class="tableblock halign-left valign-top"></td>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">windows</p></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>posix::default_launcher</code></p></td>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">fork & an error pipe</p></td>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">most of posix</p></td>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">posix</p></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>posix::fork_and_forget</code></p></td>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">fork without error pipe</p></td>
|
|
<td class="tableblock halign-left valign-top"></td>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">posix</p></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>posix::vfork_launcher</code></p></td>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">vfork</p></td>
|
|
<td class="tableblock halign-left valign-top"></td>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">posix</p></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<div class="paragraph">
|
|
<p>A launcher is invoked through the call operator.</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"><span class="k">auto</span> <span class="n">l</span> <span class="o">=</span> <span class="n">windows</span><span class="o">::</span><span class="n">as_user_launcher</span><span class="p">((</span><span class="n">HANDLE</span><span class="p">)</span><span class="mh">0xDEADBEEF</span><span class="p">);</span>
|
|
<span class="n">asio</span><span class="o">::</span><span class="n">io_context</span> <span class="n">ctx</span><span class="p">;</span>
|
|
<span class="n">boost</span><span class="o">::</span><span class="n">system</span><span class="o">::</span><span class="n">error_code</span> <span class="n">ec</span><span class="p">;</span>
|
|
<span class="k">auto</span> <span class="n">proc</span> <span class="o">=</span> <span class="n">l</span><span class="p">(</span><span class="n">ctx</span><span class="p">,</span> <span class="n">ec</span><span class="p">,</span> <span class="s">"C:</span><span class="se">\\</span><span class="s">User</span><span class="se">\\</span><span class="s">boost</span><span class="se">\\</span><span class="s">Downloads</span><span class="se">\\</span><span class="s">totally_not_a_virus.exe"</span><span class="p">,</span> <span class="p">{});</span></code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The launcher will call certain functions on the initializer if they’re present, as documented below.
|
|
The initializer are used to modify the process behaviour.</p>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="linux_launchers">Linux Launchers</h3>
|
|
<div class="paragraph">
|
|
<p>The default launchers on linux open an internal pipe to communicate errors that occur after forking back to the parent process.</p>
|
|
</div>
|
|
<div class="admonitionblock note">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-note" title="Note"></i>
|
|
</td>
|
|
<td class="content">
|
|
A pipe can be used if one end is open on the parent, the other on the child.
|
|
This allows the parents to select on his pipe-end to know if the child exited.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>This can be prevented by using the <code>fork_and_forget_launcher</code>.
|
|
Alternatively, the <code>vfork_launcher</code> can report errors directly back to the parent process.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>Thus some calls to the initializers occur after forking from the child process.</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"><span class="k">struct</span> <span class="nc">custom_initializer</span>
|
|
<span class="p">{</span>
|
|
<span class="c1">// called before a call to fork. A returned error will cancel the launch.</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Launcher</span><span class="p">></span>
|
|
<span class="n">error_code</span> <span class="n">on_setup</span><span class="p">(</span><span class="n">Launcher</span> <span class="o">&</span> <span class="n">launcher</span><span class="p">,</span> <span class="k">const</span> <span class="n">filesystem</span><span class="o">::</span><span class="n">path</span> <span class="o">&</span><span class="n">executable</span><span class="p">,</span> <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span> <span class="k">const</span> <span class="o">*</span> <span class="p">(</span><span class="o">&</span><span class="n">cmd_line</span><span class="p">));</span>
|
|
|
|
<span class="c1">// called for every initializer if an error occurred during setup or process creation</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Launcher</span><span class="p">></span>
|
|
<span class="kt">void</span> <span class="n">on_error</span><span class="p">(</span><span class="n">Launcher</span> <span class="o">&</span> <span class="n">launcher</span><span class="p">,</span> <span class="k">const</span> <span class="n">filesystem</span><span class="o">::</span><span class="n">path</span> <span class="o">&</span><span class="n">executable</span><span class="p">,</span> <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span> <span class="k">const</span> <span class="o">*</span> <span class="p">(</span><span class="o">&</span><span class="n">cmd_line</span><span class="p">),</span>
|
|
<span class="k">const</span> <span class="n">error_code</span> <span class="o">&</span> <span class="n">ec</span><span class="p">);</span>
|
|
|
|
<span class="c1">// called after successful process creation</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Launcher</span><span class="p">></span>
|
|
<span class="kt">void</span> <span class="n">on_success</span><span class="p">(</span><span class="n">Launcher</span> <span class="o">&</span> <span class="n">launcher</span><span class="p">,</span> <span class="k">const</span> <span class="n">filesystem</span><span class="o">::</span><span class="n">path</span> <span class="o">&</span><span class="n">executable</span><span class="p">,</span> <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span> <span class="k">const</span> <span class="o">*</span> <span class="p">(</span><span class="o">&</span><span class="n">cmd_line</span><span class="p">));</span>
|
|
|
|
<span class="c1">// called for every initializer if an error occurred when forking, in addition to on_error.</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Launcher</span><span class="p">></span>
|
|
<span class="kt">void</span> <span class="n">on_fork_error</span><span class="p">(</span><span class="n">Launcher</span> <span class="o">&</span> <span class="n">launcher</span><span class="p">,</span> <span class="k">const</span> <span class="n">filesystem</span><span class="o">::</span><span class="n">path</span> <span class="o">&</span><span class="n">executable</span><span class="p">,</span> <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span> <span class="k">const</span> <span class="o">*</span> <span class="p">(</span><span class="o">&</span><span class="n">cmd_line</span><span class="p">),</span>
|
|
<span class="k">const</span> <span class="n">error_code</span> <span class="o">&</span> <span class="n">ec</span><span class="p">);</span>
|
|
|
|
|
|
<span class="c1">// called before a call to execve. A returned error will cancel the launch. Called from the child process.</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Launcher</span><span class="p">></span>
|
|
<span class="n">error_code</span> <span class="n">on_exec_setup</span><span class="p">(</span><span class="n">Launcher</span> <span class="o">&</span> <span class="n">launcher</span><span class="p">,</span> <span class="k">const</span> <span class="n">filesystem</span><span class="o">::</span><span class="n">path</span> <span class="o">&</span><span class="n">executable</span><span class="p">,</span> <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span> <span class="k">const</span> <span class="o">*</span> <span class="p">(</span><span class="o">&</span><span class="n">cmd_line</span><span class="p">));</span>
|
|
|
|
|
|
<span class="c1">// called after a failed call to execve from the child process.</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Launcher</span><span class="p">></span>
|
|
<span class="kt">void</span> <span class="n">on_exec_error</span><span class="p">(</span><span class="n">Launcher</span> <span class="o">&</span> <span class="n">launcher</span><span class="p">,</span> <span class="k">const</span> <span class="n">filesystem</span><span class="o">::</span><span class="n">path</span> <span class="o">&</span><span class="n">executable</span><span class="p">,</span> <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span> <span class="k">const</span> <span class="o">*</span> <span class="p">(</span><span class="o">&</span><span class="n">cmd_line</span><span class="p">));</span>
|
|
<span class="p">};</span></code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The call sequence on success:</p>
|
|
</div>
|
|
<div class="imageblock">
|
|
<div class="content">
|
|
<img src="./images/posix_success.svg" alt="posix success">
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The call sequence when fork fails:</p>
|
|
</div>
|
|
<div class="imageblock">
|
|
<div class="content">
|
|
<img src="./images/posix_fork_err.svg" alt="posix fork err">
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The call sequence when exec fails:</p>
|
|
</div>
|
|
<div class="imageblock">
|
|
<div class="content">
|
|
<img src="./images/posix_exec_err.svg" alt="posix exec err">
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The launcher will close all non-whitelisted file descriptors after <code>on_exec_setup</code>.</p>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="windows_launchers">Windows Launchers</h3>
|
|
<div class="paragraph">
|
|
<p>Windows launchers are pretty straight forward, they will call the following functions on the initializer if present.</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"><span class="k">struct</span> <span class="nc">custom_initializer</span>
|
|
<span class="p">{</span>
|
|
<span class="c1">// called before a call to CreateProcess. A returned error will cancel the launch.</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Launcher</span><span class="p">></span>
|
|
<span class="n">error_code</span> <span class="n">on_setup</span><span class="p">(</span><span class="n">Launcher</span> <span class="o">&</span> <span class="n">launcher</span><span class="p">,</span> <span class="k">const</span> <span class="n">filesystem</span><span class="o">::</span><span class="n">path</span> <span class="o">&</span><span class="n">executable</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">wstring</span> <span class="o">&</span><span class="n">cmd_line</span><span class="p">);</span>
|
|
|
|
<span class="c1">// called for every initializer if an error occurred during setup or process creation</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Launcher</span><span class="p">></span>
|
|
<span class="kt">void</span> <span class="n">on_error</span><span class="p">(</span><span class="n">Launcher</span> <span class="o">&</span> <span class="n">launcher</span><span class="p">,</span> <span class="k">const</span> <span class="n">filesystem</span><span class="o">::</span><span class="n">path</span> <span class="o">&</span><span class="n">executable</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">wstring</span> <span class="o">&</span><span class="n">cmd_line</span><span class="p">,</span>
|
|
<span class="k">const</span> <span class="n">error_code</span> <span class="o">&</span> <span class="n">ec</span><span class="p">);</span>
|
|
|
|
<span class="c1">// called after successful process creation</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Launcher</span><span class="p">></span>
|
|
<span class="kt">void</span> <span class="n">on_success</span><span class="p">(</span><span class="n">Launcher</span> <span class="o">&</span> <span class="n">launcher</span><span class="p">,</span> <span class="k">const</span> <span class="n">filesystem</span><span class="o">::</span><span class="n">path</span> <span class="o">&</span><span class="n">executable</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">wstring</span> <span class="o">&</span><span class="n">cmd_line</span><span class="p">);</span>
|
|
|
|
<span class="p">};</span></code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="admonitionblock note">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-note" title="Note"></i>
|
|
</td>
|
|
<td class="content">
|
|
All the additional launchers for windows inherit <code>default_launcher</code>.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The call sequence is as follows:</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>image::windows_exec.svg
|
|
'''</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect1">
|
|
<h2 id="initializers">Initializers</h2>
|
|
<div class="sectionbody">
|
|
<div class="sect2">
|
|
<h3 id="process_start_dir"><code>process_start_dir</code></h3>
|
|
<div class="paragraph">
|
|
<p>The easier initializer to use is <code>process_start_dir</code>:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="title">example/start_dir.cpp:17-20</div>
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"><span class="n">asio</span><span class="o">::</span><span class="n">io_context</span> <span class="n">ctx</span><span class="p">;</span>
|
|
<span class="n">process</span> <span class="nf">ls</span><span class="p">(</span><span class="n">ctx</span><span class="p">.</span><span class="n">get_executor</span><span class="p">(),</span> <span class="s">"/ls"</span><span class="p">,</span> <span class="p">{},</span> <span class="n">process_start_dir</span><span class="p">(</span><span class="s">"/home"</span><span class="p">));</span>
|
|
<span class="n">ls</span><span class="p">.</span><span class="n">wait</span><span class="p">();</span></code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>This will run <code>ls</code> in the folder <code>/home</code> instead of the current folder.</p>
|
|
</div>
|
|
<div class="admonitionblock warning">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-warning" title="Warning"></i>
|
|
</td>
|
|
<td class="content">
|
|
If your path is relative, it may fail on posix, because the directory is changed before a call to execve.
|
|
= stdio
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>When using io with a subprocess, all three standard streams (stdin, stdout, stderr) get set for the child-process.
|
|
The default setting is to inherit the parent process.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>This feature meant to be flexible, which is why there is little checking on the arguments assigned to one of those streams.</p>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="pipes">Pipes</h3>
|
|
<div class="paragraph">
|
|
<p>asio pipes can be used for io. When using in process_stdio they will get
|
|
automatically connected and the other side will get assigned to the child process:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="title">example/stdio.cpp:20-29</div>
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"><span class="n">asio</span><span class="o">::</span><span class="n">io_context</span> <span class="n">ctx</span><span class="p">;</span>
|
|
<span class="n">asio</span><span class="o">::</span><span class="n">readable_pipe</span> <span class="n">rp</span><span class="p">{</span><span class="n">ctx</span><span class="p">};</span>
|
|
|
|
<span class="n">process</span> <span class="nf">proc</span><span class="p">(</span><span class="n">ctx</span><span class="p">,</span> <span class="s">"/usr/bin/g++"</span><span class="p">,</span> <span class="p">{</span><span class="s">"--version"</span><span class="p">},</span> <span class="n">process_stdio</span><span class="p">{{</span> <span class="cm">/* in to default */</span><span class="p">},</span> <span class="n">rp</span><span class="p">,</span> <span class="p">{</span> <span class="cm">/* err to default */</span> <span class="p">}});</span>
|
|
<span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">output</span><span class="p">;</span>
|
|
|
|
<span class="n">boost</span><span class="o">::</span><span class="n">system</span><span class="o">::</span><span class="n">error_code</span> <span class="n">ec</span><span class="p">;</span>
|
|
<span class="n">asio</span><span class="o">::</span><span class="n">read</span><span class="p">(</span><span class="n">rp</span><span class="p">,</span> <span class="n">asio</span><span class="o">::</span><span class="n">dynamic_buffer</span><span class="p">(</span><span class="n">output</span><span class="p">),</span> <span class="n">ec</span><span class="p">);</span>
|
|
<span class="n">assert</span><span class="p">(</span><span class="o">!</span><span class="n">ec</span> <span class="o">||</span> <span class="p">(</span><span class="n">ec</span> <span class="o">==</span> <span class="n">asio</span><span class="o">::</span><span class="n">error</span><span class="o">::</span><span class="n">eof</span><span class="p">));</span>
|
|
<span class="n">proc</span><span class="p">.</span><span class="n">wait</span><span class="p">();</span></code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>readable pipes can be assigned to <code>out</code> and <code>err</code>, while writable_pipes can be assigned to <code>in</code>.</p>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="file"><code>FILE*</code></h3>
|
|
<div class="paragraph">
|
|
<p><code>FILE*</code> can also be used for either side; this allows the <code>stdin</code>, <code>stderr</code>, <code>stdout</code> macros to be used:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="title">example/stdio.cpp:35-38</div>
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"> <span class="n">asio</span><span class="o">::</span><span class="n">io_context</span> <span class="n">ctx</span><span class="p">;</span>
|
|
<span class="c1">// forward both stderr & stdout to stdout of the parent process</span>
|
|
<span class="n">process</span> <span class="nf">proc</span><span class="p">(</span><span class="n">ctx</span><span class="p">,</span> <span class="s">"/usr/bin/g++"</span><span class="p">,</span> <span class="p">{</span><span class="s">"--version"</span><span class="p">},</span> <span class="n">process_stdio</span><span class="p">{{</span> <span class="cm">/* in to default */</span><span class="p">},</span> <span class="n">stdout</span><span class="p">,</span> <span class="n">stdout</span><span class="p">});</span>
|
|
<span class="n">proc</span><span class="p">.</span><span class="n">wait</span><span class="p">();</span></code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="nullptr"><code>nullptr</code></h3>
|
|
<div class="paragraph">
|
|
<p><code>nullptr</code> may be used to set a given stream to be opened on the null-device (<code>/dev/null</code> on posix, <code>NUL</code> on windows).
|
|
This is used to ignore output or give only EOF as input.</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="title">example/stdio.cpp:43-46</div>
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"> <span class="n">asio</span><span class="o">::</span><span class="n">io_context</span> <span class="n">ctx</span><span class="p">;</span>
|
|
<span class="c1">// forward stderr to /dev/null or NUL</span>
|
|
<span class="n">process</span> <span class="nf">proc</span><span class="p">(</span><span class="n">ctx</span><span class="p">,</span> <span class="s">"/usr/bin/g++"</span><span class="p">,</span> <span class="p">{</span><span class="s">"--version"</span><span class="p">},</span> <span class="n">process_stdio</span><span class="p">{{</span> <span class="cm">/* in to default */</span><span class="p">},</span> <span class="p">{},</span> <span class="nb">nullptr</span><span class="p">});</span>
|
|
<span class="n">proc</span><span class="p">.</span><span class="n">wait</span><span class="p">();</span></code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="native_handle"><code>native_handle</code></h3>
|
|
<div class="paragraph">
|
|
<p>A native handle can be used as well, which means an <code>int</code> on posix or a <code>HANDLE</code> on windows.
|
|
Furthermore, any object that has a <code>native_handle</code> function which returns a valid type for a stdio stream.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>E.g. a domain socket on linux.</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="title">example/stdio.cpp:52-57</div>
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"> <span class="n">asio</span><span class="o">::</span><span class="n">io_context</span> <span class="n">ctx</span><span class="p">;</span>
|
|
<span class="c1">// ignore stderr</span>
|
|
<span class="n">asio</span><span class="o">::</span><span class="n">local</span><span class="o">::</span><span class="n">stream_protocol</span><span class="o">::</span><span class="n">socket</span> <span class="n">sock</span><span class="p">{</span><span class="n">ctx</span><span class="p">},</span> <span class="n">other</span><span class="p">{</span><span class="n">ctx</span><span class="p">};</span>
|
|
<span class="n">asio</span><span class="o">::</span><span class="n">local</span><span class="o">::</span><span class="n">connect_pair</span><span class="p">(</span><span class="n">sock</span><span class="p">,</span> <span class="n">other</span><span class="p">);</span>
|
|
<span class="n">process</span> <span class="nf">proc</span><span class="p">(</span><span class="n">ctx</span><span class="p">,</span> <span class="s">"~/not-a-virus"</span><span class="p">,</span> <span class="p">{},</span> <span class="n">process_stdio</span><span class="p">{</span><span class="n">sock</span><span class="p">,</span> <span class="n">sock</span><span class="p">,</span> <span class="nb">nullptr</span><span class="p">});</span>
|
|
<span class="n">proc</span><span class="p">.</span><span class="n">wait</span><span class="p">();</span></code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="popen">popen</h3>
|
|
<div class="paragraph">
|
|
<p>Additionally, process v2 provides a <code>popen</code> class.
|
|
It starts a process and connects pipes for stdin and stdout, so that the popen object can be used as a stream.</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="title">example/stdio.cpp:63-66</div>
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"> <span class="n">asio</span><span class="o">::</span><span class="n">io_context</span> <span class="n">ctx</span><span class="p">;</span>
|
|
<span class="n">boost</span><span class="o">::</span><span class="n">process</span><span class="o">::</span><span class="n">popen</span> <span class="nf">proc</span><span class="p">(</span><span class="n">ctx</span><span class="p">,</span> <span class="s">"/usr/bin/addr2line"</span><span class="p">,</span> <span class="p">{</span><span class="n">argv</span><span class="p">[</span><span class="mi">0</span><span class="p">]});</span>
|
|
<span class="n">asio</span><span class="o">::</span><span class="n">write</span><span class="p">(</span><span class="n">proc</span><span class="p">,</span> <span class="n">asio</span><span class="o">::</span><span class="n">buffer</span><span class="p">(</span><span class="s">"main</span><span class="se">\n</span><span class="s">"</span><span class="p">));</span>
|
|
<span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">line</span><span class="p">;</span>
|
|
<span class="n">asio</span><span class="o">::</span><span class="n">read_until</span><span class="p">(</span><span class="n">proc</span><span class="p">,</span> <span class="n">asio</span><span class="o">::</span><span class="n">dynamic_buffer</span><span class="p">(</span><span class="n">line</span><span class="p">),</span> <span class="sc">'\n'</span><span class="p">);</span></code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="environment">Environment</h3>
|
|
<div class="paragraph">
|
|
<p>The <code>environment</code> namespace provides all sorts of facilities to query and manipulate the environment of the current process.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The api should be straight forward, but one oddity that needs to be pointed out is, that environment names
|
|
are not case sensitive on windows. The key_traits class implements the proper traits depending on the current system.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>Additionally, environment can be lists separated by <code>:</code> or <code>;</code>; <code>environment::value</code> and
|
|
<code>environment::value_view</code> can be used to iterate those.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>Beyond that, the requirements on an environment are a low as possible;
|
|
an environment is either a list of strings or a list of string-pairs. It is however recommended to use the environment types,
|
|
as to have the right value comparisons.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>To note is the <code>find_executable</code> functions, which searches in an environment for an executable.</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="title">example/env.cpp:19-28</div>
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"> <span class="c1">// search in the current environment</span>
|
|
<span class="k">auto</span> <span class="n">exe</span> <span class="o">=</span> <span class="n">environment</span><span class="o">::</span><span class="n">find_executable</span><span class="p">(</span><span class="s">"g++"</span><span class="p">);</span>
|
|
|
|
<span class="n">std</span><span class="o">::</span><span class="n">unordered_map</span> <span class="o"><</span><span class="n">environment</span><span class="o">::</span><span class="n">key</span><span class="p">,</span> <span class="n">environment</span><span class="o">::</span><span class="n">value</span><span class="o">></span> <span class="n">my_env</span> <span class="o">=</span>
|
|
<span class="p">{</span>
|
|
<span class="p">{</span><span class="s">"SECRET"</span><span class="p">,</span> <span class="s">"THIS_IS_A_TEST"</span><span class="p">},</span>
|
|
<span class="p">{</span><span class="s">"PATH"</span><span class="p">,</span> <span class="p">{</span><span class="s">"/bin"</span><span class="p">,</span> <span class="s">"/usr/bin"</span><span class="p">}}</span>
|
|
<span class="p">};</span>
|
|
|
|
<span class="k">auto</span> <span class="n">other_exe</span> <span class="o">=</span> <span class="n">environment</span><span class="o">::</span><span class="n">find_executable</span><span class="p">(</span><span class="s">"g++"</span><span class="p">,</span> <span class="n">my_env</span><span class="p">);</span></code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="subprocess_environment">Subprocess environment</h3>
|
|
<div class="paragraph">
|
|
<p>The subprocess environment assignment follows the same constraints:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="title">example/env.cpp:34-42</div>
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"><span class="n">asio</span><span class="o">::</span><span class="n">io_context</span> <span class="n">ctx</span><span class="p">;</span>
|
|
<span class="n">std</span><span class="o">::</span><span class="n">unordered_map</span><span class="o"><</span><span class="n">environment</span><span class="o">::</span><span class="n">key</span><span class="p">,</span> <span class="n">environment</span><span class="o">::</span><span class="n">value</span><span class="o">></span> <span class="n">my_env</span> <span class="o">=</span>
|
|
<span class="p">{</span>
|
|
<span class="p">{</span><span class="s">"SECRET"</span><span class="p">,</span> <span class="s">"THIS_IS_A_TEST"</span><span class="p">},</span>
|
|
<span class="p">{</span><span class="s">"PATH"</span><span class="p">,</span> <span class="p">{</span><span class="s">"/bin"</span><span class="p">,</span> <span class="s">"/usr/bin"</span><span class="p">}}</span>
|
|
<span class="p">};</span>
|
|
<span class="k">auto</span> <span class="n">exe</span> <span class="o">=</span> <span class="n">environment</span><span class="o">::</span><span class="n">find_executable</span><span class="p">(</span><span class="s">"g++"</span><span class="p">,</span> <span class="n">my_env</span><span class="p">);</span>
|
|
<span class="n">process</span> <span class="nf">proc</span><span class="p">(</span><span class="n">ctx</span><span class="p">,</span> <span class="n">exe</span><span class="p">,</span> <span class="p">{</span><span class="s">"main.cpp"</span><span class="p">},</span> <span class="n">process_environment</span><span class="p">(</span><span class="n">my_env</span><span class="p">));</span>
|
|
<span class="n">process</span> <span class="nf">pro2</span><span class="p">(</span><span class="n">ctx</span><span class="p">,</span> <span class="n">exe</span><span class="p">,</span> <span class="p">{</span><span class="s">"test.cpp"</span><span class="p">},</span> <span class="n">process_environment</span><span class="p">(</span><span class="n">my_env</span><span class="p">));</span></code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="inheriting_an_environment">Inheriting an environment</h3>
|
|
<div class="paragraph">
|
|
<p>The current environment can be obtained by calling <code>environment::current</code> which returns
|
|
a forward range of <code>environment::key_value_pair_view</code>.</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="title">example/env.cpp:48-54</div>
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"><span class="n">asio</span><span class="o">::</span><span class="n">io_context</span> <span class="n">ctx</span><span class="p">;</span>
|
|
<span class="k">auto</span> <span class="n">c</span> <span class="o">=</span> <span class="n">environment</span><span class="o">::</span><span class="n">current</span><span class="p">();</span>
|
|
<span class="c1">// we need to use a value, since windows needs wchar_t.</span>
|
|
<span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">environment</span><span class="o">::</span><span class="n">key_value_pair</span><span class="o">></span> <span class="n">my_env</span><span class="p">{</span><span class="n">c</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">c</span><span class="p">.</span><span class="n">end</span><span class="p">()};</span>
|
|
<span class="n">my_env</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="s">"SECRET=THIS_IS_A_TEST"</span><span class="p">);</span>
|
|
<span class="k">auto</span> <span class="n">exe</span> <span class="o">=</span> <span class="n">environment</span><span class="o">::</span><span class="n">find_executable</span><span class="p">(</span><span class="s">"g++"</span><span class="p">,</span> <span class="n">my_env</span><span class="p">);</span>
|
|
<span class="n">process</span> <span class="nf">proc</span><span class="p">(</span><span class="n">ctx</span><span class="p">,</span> <span class="n">exe</span><span class="p">,</span> <span class="p">{</span><span class="s">"main.cpp"</span><span class="p">},</span> <span class="n">process_environment</span><span class="p">(</span><span class="n">my_env</span><span class="p">));</span></code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>Alternatively you can use a map container for the environment.</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="title">example/env.cpp:61-68</div>
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"><span class="n">asio</span><span class="o">::</span><span class="n">io_context</span> <span class="n">ctx</span><span class="p">;</span>
|
|
<span class="n">std</span><span class="o">::</span><span class="n">unordered_map</span><span class="o"><</span><span class="n">environment</span><span class="o">::</span><span class="n">key</span><span class="p">,</span> <span class="n">environment</span><span class="o">::</span><span class="n">value</span><span class="o">></span> <span class="n">my_env</span><span class="p">;</span>
|
|
<span class="k">for</span> <span class="p">(</span><span class="k">const</span> <span class="k">auto</span> <span class="o">&</span> <span class="n">kv</span> <span class="o">:</span> <span class="n">environment</span><span class="o">::</span><span class="n">current</span><span class="p">())</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="n">kv</span><span class="p">.</span><span class="n">key</span><span class="p">().</span><span class="n">string</span><span class="p">()</span> <span class="o">!=</span> <span class="s">"SECRET"</span><span class="p">)</span>
|
|
<span class="n">my_env</span><span class="p">[</span><span class="n">kv</span><span class="p">.</span><span class="n">key</span><span class="p">()]</span> <span class="o">=</span> <span class="n">kv</span><span class="p">.</span><span class="n">value</span><span class="p">();</span>
|
|
|
|
<span class="k">auto</span> <span class="n">exe</span> <span class="o">=</span> <span class="n">environment</span><span class="o">::</span><span class="n">find_executable</span><span class="p">(</span><span class="s">"g++"</span><span class="p">,</span> <span class="n">my_env</span><span class="p">);</span>
|
|
<span class="n">process</span> <span class="nf">proc</span><span class="p">(</span><span class="n">ctx</span><span class="p">,</span> <span class="n">exe</span><span class="p">,</span> <span class="p">{</span><span class="s">"main.cpp"</span><span class="p">},</span> <span class="n">process_environment</span><span class="p">(</span><span class="n">my_env</span><span class="p">));</span></code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect1">
|
|
<h2 id="reference">Reference</h2>
|
|
<div class="sectionbody">
|
|
<div class="sect2">
|
|
<h3 id="bind_launcher_hpp"><code>bind_launcher.hpp</code></h3>
|
|
<div class="paragraph">
|
|
<p>The <code>bind_launcher</code> utilities allow on the fly construction of a launcher with bound initializers.</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"><span class="c1">// Creates a new launcher with the bound initializer.</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Launcher</span><span class="p">,</span> <span class="k">typename</span> <span class="o">...</span> <span class="nc">Init</span><span class="p">></span>
|
|
<span class="k">auto</span> <span class="nf">bind_launcher</span><span class="p">(</span><span class="n">Launcher</span> <span class="o">&&</span> <span class="n">launcher</span><span class="p">,</span> <span class="n">Init</span> <span class="o">&&</span> <span class="p">...</span> <span class="n">init</span><span class="p">);</span>
|
|
|
|
<span class="c1">// Calls bind_launcher with the default_launcher as the first parameter.</span>
|
|
<span class="c1">// The new launcher with bound parameters</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="o">...</span> <span class="nc">Init</span><span class="p">></span>
|
|
<span class="k">auto</span> <span class="nf">bind_default_launcher</span><span class="p">(</span><span class="n">Init</span> <span class="o">&&</span> <span class="p">...</span> <span class="n">init</span><span class="p">);</span></code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="cstring_ref_hpp"><code>cstring_ref.hpp</code></h3>
|
|
<div class="paragraph">
|
|
<p>The <code>cstring_ref</code> is a string-view like type that holds a null-terminated string.
|
|
== <code>default_launcher.hpp</code></p>
|
|
</div>
|
|
<div id="default_launcher" class="paragraph">
|
|
<p>The <code>default_launcher</code> is the standard way of creating a process.</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"><span class="n">asio</span><span class="o">::</span><span class="n">io_context</span> <span class="n">ctx</span><span class="p">;</span>
|
|
<span class="n">process</span> <span class="nf">proc</span><span class="p">(</span><span class="n">ctx</span><span class="p">.</span><span class="n">get_executor</span><span class="p">(),</span> <span class="s">"test"</span><span class="p">,</span> <span class="p">{});</span>
|
|
<span class="c1">// equivalent to</span>
|
|
<span class="n">process</span> <span class="n">proc</span> <span class="o">=</span> <span class="n">default_launcher</span><span class="p">()(</span><span class="n">ctx</span><span class="p">.</span><span class="n">get_executor</span><span class="p">(),</span> <span class="s">"test"</span><span class="p">,</span> <span class="p">{});</span></code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>It has four overloads:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"><span class="p">(</span><span class="n">ExecutionContext</span> <span class="o">&</span><span class="p">,</span> <span class="n">filesystem</span><span class="o">::</span><span class="n">path</span><span class="p">,</span> <span class="n">Args</span> <span class="o">&&</span> <span class="n">args</span><span class="p">,</span> <span class="n">Inits</span> <span class="o">&&</span> <span class="p">...</span> <span class="n">inits</span><span class="p">)</span> <span class="o">-></span> <span class="n">basic_process</span><span class="o"><</span><span class="k">typename</span> <span class="n">ExecutionContext</span><span class="o">::</span><span class="n">executor_type</span><span class="o">></span>
|
|
<span class="p">(</span><span class="n">Executor</span> <span class="o">&</span><span class="p">,</span> <span class="n">filesystem</span><span class="o">::</span><span class="n">path</span><span class="p">,</span> <span class="n">Args</span> <span class="o">&&</span> <span class="n">args</span><span class="p">,</span> <span class="n">Inits</span> <span class="o">&&</span> <span class="p">...</span> <span class="n">inits</span><span class="p">)</span> <span class="o">-></span> <span class="n">basic_process</span><span class="o"><</span><span class="n">Executor</span><span class="o">></span><span class="p">;</span>
|
|
<span class="p">(</span><span class="n">ExecutionContext</span> <span class="o">&</span><span class="p">,</span> <span class="n">error_code</span><span class="o">&</span><span class="p">,</span> <span class="n">filesystem</span><span class="o">::</span><span class="n">path</span><span class="p">,</span> <span class="n">Args</span> <span class="o">&&</span> <span class="n">args</span><span class="p">,</span> <span class="n">Inits</span> <span class="o">&&</span> <span class="p">...</span> <span class="n">inits</span><span class="p">)</span> <span class="o">-></span> <span class="n">basic_process</span><span class="o"><</span><span class="k">typename</span> <span class="n">ExecutionContext</span><span class="o">::</span><span class="n">executor_type</span><span class="o">></span><span class="p">;</span><span class="err">`</span>
|
|
<span class="p">(</span><span class="n">Executor</span> <span class="o">&</span><span class="p">,</span> <span class="n">error_code</span><span class="o">&</span><span class="p">,</span> <span class="n">filesystem</span><span class="o">::</span><span class="n">path</span><span class="p">,</span> <span class="n">Args</span> <span class="o">&&</span> <span class="n">args</span><span class="p">,</span> <span class="n">Inits</span> <span class="o">&&</span> <span class="p">...</span> <span class="n">inits</span><span class="p">)</span> <span class="o">-></span> <span class="n">basic_process</span><span class="o"><</span><span class="n">Executor</span><span class="o">></span></code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="environment_hpp"><code>environment.hpp</code></h3>
|
|
<div class="sect3">
|
|
<h4 id="environment"><code>environment</code></h4>
|
|
<div class="paragraph">
|
|
<p>The <code>environment</code> header provides facilities to manipulate the current environment and set it for new processes.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>An environment is a a <code>range</code> of <code>T</code> fulfilling these requirements:</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>For <code>T value</code>
|
|
* - std::get<0>(value) must return a type comparable to <code>key_view</code>.
|
|
* - std::get<1>(value) must return a type convertible to <code>value_view</code>.</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"><span class="c1">// Namespace for information and functions regarding the calling process.</span>
|
|
<span class="k">namespace</span> <span class="n">environment</span>
|
|
<span class="p">{</span>
|
|
|
|
<span class="c1">// A char traits type that reflects the OS rules for string representing environment keys.</span>
|
|
<span class="cm">/* Can be an alias of std::char_traits. May only be defined for `char` and `wchar_t`.
|
|
*
|
|
* Windows treats keys as case-insensitive yet preserving. The char traits are made to reflect
|
|
* that behaviour.
|
|
*/</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Char</span><span class="p">></span>
|
|
<span class="k">using</span> <span class="n">key_char_traits</span> <span class="o">=</span> <span class="n">implementation_defined</span> <span class="p">;</span>
|
|
|
|
<span class="c1">// A char traits type that reflects the OS rules for string representing environment values.</span>
|
|
<span class="cm">/* Can be an alias of std::char_traits. May only be defined for `char` and `wchar_t`.
|
|
*/</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Char</span><span class="p">></span>
|
|
<span class="k">using</span> <span class="n">value_char_traits</span> <span class="o">=</span> <span class="n">implementation_defined</span> <span class="p">;</span>
|
|
|
|
<span class="c1">// The character type used by the environment. Either `char` or `wchar_t`.</span>
|
|
<span class="k">using</span> <span class="n">char_type</span> <span class="o">=</span> <span class="n">implementation_defined</span> <span class="p">;</span>
|
|
|
|
<span class="c1">// The equal character in an environment string used to separate key and value.</span>
|
|
<span class="k">constexpr</span> <span class="n">char_type</span> <span class="n">equality_sign</span> <span class="o">=</span> <span class="n">implementation_defined</span><span class="p">;</span>
|
|
|
|
<span class="c1">// The delimiter in environemtn lists. Commonly used by the `PATH` variable.</span>
|
|
<span class="k">constexpr</span> <span class="n">char_type</span> <span class="n">delimiter</span> <span class="o">=</span> <span class="n">implementation_defined</span><span class="p">;</span>
|
|
|
|
<span class="c1">// The native handle of an environment. Note that this can be an owning pointer and is generally not thread safe.</span>
|
|
<span class="k">using</span> <span class="n">native_handle</span> <span class="o">=</span> <span class="n">implementation_defined</span><span class="p">;</span>
|
|
|
|
|
|
<span class="c1">// A forward iterator over string_view used by a value or value_view to iterator through environments that are lists.</span>
|
|
<span class="k">struct</span> <span class="nc">value_iterator</span><span class="p">;</span>
|
|
|
|
<span class="c1">// A view type for a key of an environment</span>
|
|
<span class="k">struct</span> <span class="nc">key_view</span>
|
|
<span class="p">{</span>
|
|
<span class="k">using</span> <span class="n">value_type</span> <span class="o">=</span> <span class="n">char_type</span><span class="p">;</span>
|
|
<span class="k">using</span> <span class="n">traits_type</span> <span class="o">=</span> <span class="n">key_char_traits</span><span class="o"><</span><span class="n">char_type</span><span class="o">></span><span class="p">;</span>
|
|
<span class="k">using</span> <span class="n">string_view_type</span> <span class="o">=</span> <span class="n">basic_string_view</span><span class="o"><</span><span class="n">char_type</span><span class="p">,</span> <span class="n">traits_type</span><span class="o">></span><span class="p">;</span>
|
|
<span class="k">using</span> <span class="n">string_type</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">basic_string</span><span class="o"><</span><span class="n">char_type</span><span class="p">,</span> <span class="n">key_char_traits</span><span class="o"><</span><span class="n">char_type</span><span class="o">>></span><span class="p">;</span>
|
|
|
|
<span class="n">key_view</span><span class="p">()</span> <span class="k">noexcept</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
|
|
<span class="n">key_view</span><span class="p">(</span> <span class="k">const</span> <span class="n">key_view</span><span class="o">&</span> <span class="n">p</span> <span class="p">)</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
|
|
<span class="n">key_view</span><span class="p">(</span> <span class="n">key_view</span><span class="o">&&</span> <span class="n">p</span> <span class="p">)</span> <span class="k">noexcept</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Source</span><span class="p">></span>
|
|
<span class="n">key_view</span><span class="p">(</span> <span class="k">const</span> <span class="n">Source</span><span class="o">&</span> <span class="n">source</span> <span class="p">);</span>
|
|
<span class="n">key_view</span><span class="p">(</span> <span class="k">const</span> <span class="n">char_type</span> <span class="o">*</span> <span class="n">p</span><span class="p">);</span>
|
|
<span class="n">key_view</span><span class="p">(</span> <span class="n">char_type</span> <span class="o">*</span> <span class="n">p</span><span class="p">);</span>
|
|
|
|
<span class="o">~</span><span class="n">key_view</span><span class="p">()</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
|
|
|
|
<span class="n">key_view</span><span class="o">&</span> <span class="k">operator</span><span class="o">=</span><span class="p">(</span> <span class="k">const</span> <span class="n">key_view</span><span class="o">&</span> <span class="n">p</span> <span class="p">)</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
|
|
<span class="n">key_view</span><span class="o">&</span> <span class="k">operator</span><span class="o">=</span><span class="p">(</span> <span class="n">key_view</span><span class="o">&&</span> <span class="n">p</span> <span class="p">)</span> <span class="k">noexcept</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
|
|
<span class="n">key_view</span><span class="o">&</span> <span class="k">operator</span><span class="o">=</span><span class="p">(</span> <span class="n">string_view_type</span> <span class="n">source</span> <span class="p">);</span>
|
|
|
|
<span class="kt">void</span> <span class="n">swap</span><span class="p">(</span> <span class="n">key_view</span><span class="o">&</span> <span class="n">other</span> <span class="p">)</span> <span class="k">noexcept</span><span class="p">;</span>
|
|
|
|
<span class="n">string_view_type</span> <span class="n">native</span><span class="p">()</span> <span class="k">const</span> <span class="k">noexcept</span><span class="p">;</span>
|
|
|
|
<span class="k">operator</span> <span class="n">string_view_type</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
|
|
<span class="kt">int</span> <span class="n">compare</span><span class="p">(</span> <span class="k">const</span> <span class="n">key_view</span><span class="o">&</span> <span class="n">p</span> <span class="p">)</span> <span class="k">const</span> <span class="k">noexcept</span><span class="p">;</span>
|
|
<span class="kt">int</span> <span class="n">compare</span><span class="p">(</span> <span class="n">string_view_type</span> <span class="n">str</span> <span class="p">)</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="kt">int</span> <span class="n">compare</span><span class="p">(</span> <span class="k">const</span> <span class="n">value_type</span><span class="o">*</span> <span class="n">s</span> <span class="p">)</span> <span class="k">const</span><span class="p">;</span>
|
|
|
|
<span class="k">template</span><span class="o"><</span> <span class="k">class</span> <span class="nc">CharT</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Traits</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">char_traits</span><span class="o"><</span><span class="n">CharT</span><span class="p">>,</span>
|
|
<span class="k">class</span> <span class="nc">Alloc</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">allocator</span><span class="o"><</span><span class="n">CharT</span><span class="o">></span> <span class="o">></span>
|
|
<span class="n">std</span><span class="o">::</span><span class="n">basic_string</span><span class="o"><</span><span class="n">CharT</span><span class="p">,</span><span class="n">Traits</span><span class="p">,</span><span class="n">Alloc</span><span class="o">></span>
|
|
<span class="n">basic_string</span><span class="p">(</span> <span class="k">const</span> <span class="n">Alloc</span><span class="o">&</span> <span class="n">alloc</span> <span class="o">=</span> <span class="n">Alloc</span><span class="p">())</span> <span class="k">const</span><span class="p">;</span>
|
|
|
|
<span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">string</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="n">std</span><span class="o">::</span><span class="n">wstring</span> <span class="n">wstring</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
|
|
<span class="n">string_type</span> <span class="n">native_string</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
|
|
<span class="k">friend</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o">==</span><span class="p">(</span><span class="n">key_view</span> <span class="n">l</span><span class="p">,</span> <span class="n">key_view</span> <span class="n">r</span><span class="p">);</span>
|
|
<span class="k">friend</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o">!=</span><span class="p">(</span><span class="n">key_view</span> <span class="n">l</span><span class="p">,</span> <span class="n">key_view</span> <span class="n">r</span><span class="p">);</span>
|
|
<span class="k">friend</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o"><=</span><span class="p">(</span><span class="n">key_view</span> <span class="n">l</span><span class="p">,</span> <span class="n">key_view</span> <span class="n">r</span><span class="p">);</span>
|
|
<span class="k">friend</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o">>=</span><span class="p">(</span><span class="n">key_view</span> <span class="n">l</span><span class="p">,</span> <span class="n">key_view</span> <span class="n">r</span><span class="p">);</span>
|
|
<span class="k">friend</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o"><</span> <span class="p">(</span><span class="n">key_view</span> <span class="n">l</span><span class="p">,</span> <span class="n">key_view</span> <span class="n">r</span><span class="p">);</span>
|
|
<span class="k">friend</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o">></span> <span class="p">(</span><span class="n">key_view</span> <span class="n">l</span><span class="p">,</span> <span class="n">key_view</span> <span class="n">r</span><span class="p">);</span>
|
|
|
|
<span class="kt">bool</span> <span class="n">empty</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
|
|
<span class="k">template</span><span class="o"><</span> <span class="k">class</span> <span class="nc">CharT</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Traits</span> <span class="p">></span>
|
|
<span class="k">friend</span> <span class="n">std</span><span class="o">::</span><span class="n">basic_ostream</span><span class="o"><</span><span class="n">CharT</span><span class="p">,</span><span class="n">Traits</span><span class="o">>&</span>
|
|
<span class="k">operator</span><span class="o"><<</span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="n">basic_ostream</span><span class="o"><</span><span class="n">CharT</span><span class="p">,</span><span class="n">Traits</span><span class="o">>&</span> <span class="n">os</span><span class="p">,</span> <span class="k">const</span> <span class="n">key_view</span><span class="o">&</span> <span class="n">p</span> <span class="p">);</span>
|
|
|
|
<span class="k">template</span><span class="o"><</span> <span class="k">class</span> <span class="nc">CharT</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Traits</span> <span class="p">></span>
|
|
<span class="k">friend</span> <span class="n">std</span><span class="o">::</span><span class="n">basic_istream</span><span class="o"><</span><span class="n">CharT</span><span class="p">,</span><span class="n">Traits</span><span class="o">>&</span>
|
|
<span class="k">operator</span><span class="o">>></span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="n">basic_istream</span><span class="o"><</span><span class="n">CharT</span><span class="p">,</span><span class="n">Traits</span><span class="o">>&</span> <span class="n">is</span><span class="p">,</span> <span class="n">key_view</span><span class="o">&</span> <span class="n">p</span> <span class="p">);</span>
|
|
|
|
<span class="k">const</span> <span class="n">value_type</span> <span class="o">*</span> <span class="n">data</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">size</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="p">};</span>
|
|
|
|
<span class="c1">// A view for a value in an environment</span>
|
|
<span class="k">struct</span> <span class="nc">value_view</span>
|
|
<span class="p">{</span>
|
|
<span class="k">using</span> <span class="n">value_type</span> <span class="o">=</span> <span class="n">char_type</span><span class="p">;</span>
|
|
<span class="k">using</span> <span class="n">string_view_type</span> <span class="o">=</span> <span class="n">basic_cstring_ref</span><span class="o"><</span><span class="n">char_type</span><span class="p">,</span> <span class="n">value_char_traits</span><span class="o"><</span><span class="n">char_type</span><span class="o">>></span><span class="p">;</span>
|
|
<span class="k">using</span> <span class="n">string_type</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">basic_string</span><span class="o"><</span><span class="n">char_type</span><span class="p">,</span> <span class="n">value_char_traits</span><span class="o"><</span><span class="n">char_type</span><span class="o">>></span><span class="p">;</span>
|
|
<span class="k">using</span> <span class="n">traits_type</span> <span class="o">=</span> <span class="n">value_char_traits</span><span class="o"><</span><span class="n">char_type</span><span class="o">></span><span class="p">;</span>
|
|
|
|
<span class="n">value_view</span><span class="p">()</span> <span class="k">noexcept</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
|
|
<span class="n">value_view</span><span class="p">(</span> <span class="k">const</span> <span class="n">value_view</span><span class="o">&</span> <span class="n">p</span> <span class="p">)</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
|
|
<span class="n">value_view</span><span class="p">(</span> <span class="n">value_view</span><span class="o">&&</span> <span class="n">p</span> <span class="p">)</span> <span class="k">noexcept</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Source</span><span class="p">></span>
|
|
<span class="n">value_view</span><span class="p">(</span> <span class="k">const</span> <span class="n">Source</span><span class="o">&</span> <span class="n">source</span> <span class="p">);</span>
|
|
<span class="n">value_view</span><span class="p">(</span> <span class="k">const</span> <span class="n">char_type</span> <span class="o">*</span> <span class="n">p</span><span class="p">);</span>
|
|
<span class="n">value_view</span><span class="p">(</span> <span class="n">char_type</span> <span class="o">*</span> <span class="n">p</span><span class="p">);</span>
|
|
|
|
<span class="o">~</span><span class="n">value_view</span><span class="p">()</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
|
|
|
|
<span class="n">value_view</span><span class="o">&</span> <span class="k">operator</span><span class="o">=</span><span class="p">(</span> <span class="k">const</span> <span class="n">value_view</span><span class="o">&</span> <span class="n">p</span> <span class="p">)</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
|
|
<span class="n">value_view</span><span class="o">&</span> <span class="k">operator</span><span class="o">=</span><span class="p">(</span> <span class="n">value_view</span><span class="o">&&</span> <span class="n">p</span> <span class="p">)</span> <span class="k">noexcept</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
|
|
<span class="n">value_view</span><span class="o">&</span> <span class="k">operator</span><span class="o">=</span><span class="p">(</span> <span class="n">string_view_type</span> <span class="n">source</span> <span class="p">);</span>
|
|
|
|
<span class="kt">void</span> <span class="n">swap</span><span class="p">(</span> <span class="n">value_view</span><span class="o">&</span> <span class="n">other</span> <span class="p">)</span> <span class="k">noexcept</span><span class="p">;</span>
|
|
|
|
<span class="n">string_view_type</span> <span class="n">native</span><span class="p">()</span> <span class="k">const</span> <span class="k">noexcept</span> <span class="p">;</span>
|
|
|
|
<span class="k">operator</span> <span class="n">string_view_type</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="k">operator</span> <span class="k">typename</span> <span class="n">string_view_type</span><span class="o">::</span><span class="n">string_view_type</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
|
|
<span class="kt">int</span> <span class="n">compare</span><span class="p">(</span> <span class="k">const</span> <span class="n">value_view</span><span class="o">&</span> <span class="n">p</span> <span class="p">)</span> <span class="k">const</span> <span class="k">noexcept</span><span class="p">;</span>
|
|
<span class="kt">int</span> <span class="n">compare</span><span class="p">(</span> <span class="n">string_view_type</span> <span class="n">str</span> <span class="p">)</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="kt">int</span> <span class="n">compare</span><span class="p">(</span> <span class="k">const</span> <span class="n">value_type</span><span class="o">*</span> <span class="n">s</span> <span class="p">)</span> <span class="k">const</span><span class="p">;</span>
|
|
|
|
<span class="k">template</span><span class="o"><</span> <span class="k">class</span> <span class="nc">CharT</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Traits</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">char_traits</span><span class="o"><</span><span class="n">CharT</span><span class="p">>,</span>
|
|
<span class="k">class</span> <span class="nc">Alloc</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">allocator</span><span class="o"><</span><span class="n">CharT</span><span class="o">></span> <span class="o">></span>
|
|
<span class="n">std</span><span class="o">::</span><span class="n">basic_string</span><span class="o"><</span><span class="n">CharT</span><span class="p">,</span><span class="n">Traits</span><span class="p">,</span><span class="n">Alloc</span><span class="o">></span>
|
|
<span class="n">basic_string</span><span class="p">(</span> <span class="k">const</span> <span class="n">Alloc</span><span class="o">&</span> <span class="n">alloc</span> <span class="o">=</span> <span class="n">Alloc</span><span class="p">()</span> <span class="p">)</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">string</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="n">std</span><span class="o">::</span><span class="n">wstring</span> <span class="n">wstring</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
|
|
<span class="n">string_type</span> <span class="n">native_string</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="kt">bool</span> <span class="n">empty</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
|
|
<span class="k">friend</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o">==</span><span class="p">(</span><span class="n">value_view</span> <span class="n">l</span><span class="p">,</span> <span class="n">value_view</span> <span class="n">r</span><span class="p">);</span>
|
|
<span class="k">friend</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o">!=</span><span class="p">(</span><span class="n">value_view</span> <span class="n">l</span><span class="p">,</span> <span class="n">value_view</span> <span class="n">r</span><span class="p">);</span>
|
|
<span class="k">friend</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o"><=</span><span class="p">(</span><span class="n">value_view</span> <span class="n">l</span><span class="p">,</span> <span class="n">value_view</span> <span class="n">r</span><span class="p">);</span>
|
|
<span class="k">friend</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o">>=</span><span class="p">(</span><span class="n">value_view</span> <span class="n">l</span><span class="p">,</span> <span class="n">value_view</span> <span class="n">r</span><span class="p">);</span>
|
|
<span class="k">friend</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o"><</span> <span class="p">(</span><span class="n">value_view</span> <span class="n">l</span><span class="p">,</span> <span class="n">value_view</span> <span class="n">r</span><span class="p">);</span>
|
|
<span class="k">friend</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o">></span> <span class="p">(</span><span class="n">value_view</span> <span class="n">l</span><span class="p">,</span> <span class="n">value_view</span> <span class="n">r</span><span class="p">);</span>
|
|
|
|
|
|
<span class="k">template</span><span class="o"><</span> <span class="k">class</span> <span class="nc">CharT</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Traits</span> <span class="p">></span>
|
|
<span class="k">friend</span> <span class="n">std</span><span class="o">::</span><span class="n">basic_ostream</span><span class="o"><</span><span class="n">CharT</span><span class="p">,</span><span class="n">Traits</span><span class="o">>&</span>
|
|
<span class="k">operator</span><span class="o"><<</span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="n">basic_ostream</span><span class="o"><</span><span class="n">CharT</span><span class="p">,</span><span class="n">Traits</span><span class="o">>&</span> <span class="n">os</span><span class="p">,</span> <span class="k">const</span> <span class="n">value_view</span><span class="o">&</span> <span class="n">p</span> <span class="p">);</span>
|
|
|
|
<span class="k">template</span><span class="o"><</span> <span class="k">class</span> <span class="nc">CharT</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Traits</span> <span class="p">></span>
|
|
<span class="k">friend</span> <span class="n">std</span><span class="o">::</span><span class="n">basic_istream</span><span class="o"><</span><span class="n">CharT</span><span class="p">,</span><span class="n">Traits</span><span class="o">>&</span>
|
|
<span class="k">operator</span><span class="o">>></span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="n">basic_istream</span><span class="o"><</span><span class="n">CharT</span><span class="p">,</span><span class="n">Traits</span><span class="o">>&</span> <span class="n">is</span><span class="p">,</span> <span class="n">value_view</span><span class="o">&</span> <span class="n">p</span> <span class="p">);</span>
|
|
<span class="n">value_iterator</span> <span class="n">begin</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="n">value_iterator</span> <span class="n">end</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
|
|
<span class="k">const</span> <span class="n">char_type</span> <span class="o">*</span> <span class="n">c_str</span><span class="p">();</span>
|
|
<span class="k">const</span> <span class="n">value_type</span> <span class="o">*</span> <span class="n">data</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">size</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="p">};</span>
|
|
|
|
<span class="c1">// A view for a key value pair in an environment</span>
|
|
<span class="k">struct</span> <span class="nc">key_value_pair_view</span>
|
|
<span class="p">{</span>
|
|
<span class="k">using</span> <span class="n">value_type</span> <span class="o">=</span> <span class="n">char_type</span><span class="p">;</span>
|
|
<span class="k">using</span> <span class="n">string_type</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">basic_string</span><span class="o"><</span><span class="n">char_type</span><span class="o">></span><span class="p">;</span>
|
|
<span class="k">using</span> <span class="n">string_view_type</span> <span class="o">=</span> <span class="n">basic_cstring_ref</span><span class="o"><</span><span class="n">char_type</span><span class="o">></span><span class="p">;</span>
|
|
<span class="k">using</span> <span class="n">traits_type</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">char_traits</span><span class="o"><</span><span class="n">char_type</span><span class="o">></span><span class="p">;</span>
|
|
|
|
<span class="n">key_value_pair_view</span><span class="p">()</span> <span class="k">noexcept</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
|
|
<span class="n">key_value_pair_view</span><span class="p">(</span> <span class="k">const</span> <span class="n">key_value_pair_view</span><span class="o">&</span> <span class="n">p</span> <span class="p">)</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
|
|
<span class="n">key_value_pair_view</span><span class="p">(</span> <span class="n">key_value_pair_view</span><span class="o">&&</span> <span class="n">p</span> <span class="p">)</span> <span class="k">noexcept</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Source</span><span class="p">,</span>
|
|
<span class="k">typename</span> <span class="o">=</span> <span class="k">typename</span> <span class="nc">std</span><span class="o">::</span><span class="n">enable_if</span><span class="o"><</span><span class="n">is_constructible</span><span class="o"><</span><span class="n">string_view_type</span><span class="p">,</span> <span class="n">Source</span><span class="p">></span><span class="o">::</span><span class="n">value</span><span class="o">>::</span><span class="n">type</span><span class="o">></span>
|
|
<span class="n">key_value_pair_view</span><span class="p">(</span> <span class="k">const</span> <span class="n">Source</span><span class="o">&</span> <span class="n">source</span> <span class="p">);</span>
|
|
|
|
<span class="n">key_value_pair_view</span><span class="p">(</span> <span class="k">const</span> <span class="n">char_type</span> <span class="o">*</span> <span class="n">p</span><span class="p">);</span>
|
|
<span class="n">key_value_pair_view</span><span class="p">(</span> <span class="n">char_type</span> <span class="o">*</span> <span class="n">p</span><span class="p">);</span>
|
|
|
|
|
|
<span class="o">~</span><span class="n">key_value_pair_view</span><span class="p">()</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
|
|
|
|
<span class="n">key_value_pair_view</span><span class="o">&</span> <span class="k">operator</span><span class="o">=</span><span class="p">(</span> <span class="k">const</span> <span class="n">key_value_pair_view</span><span class="o">&</span> <span class="n">p</span> <span class="p">)</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
|
|
<span class="n">key_value_pair_view</span><span class="o">&</span> <span class="k">operator</span><span class="o">=</span><span class="p">(</span> <span class="n">key_value_pair_view</span><span class="o">&&</span> <span class="n">p</span> <span class="p">)</span> <span class="k">noexcept</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
|
|
|
|
<span class="kt">void</span> <span class="n">swap</span><span class="p">(</span> <span class="n">key_value_pair_view</span><span class="o">&</span> <span class="n">other</span> <span class="p">)</span> <span class="k">noexcept</span><span class="p">;</span>
|
|
|
|
<span class="n">string_view_type</span> <span class="n">native</span><span class="p">()</span> <span class="k">const</span> <span class="k">noexcept</span><span class="p">;</span>
|
|
|
|
<span class="k">operator</span> <span class="n">string_view_type</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="k">operator</span> <span class="k">typename</span> <span class="n">string_view_type</span><span class="o">::</span><span class="n">string_view_type</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
|
|
<span class="kt">int</span> <span class="n">compare</span><span class="p">(</span> <span class="n">key_value_pair_view</span> <span class="n">p</span> <span class="p">)</span> <span class="k">const</span> <span class="k">noexcept</span><span class="p">;</span>
|
|
<span class="kt">int</span> <span class="n">compare</span><span class="p">(</span> <span class="k">const</span> <span class="n">string_type</span><span class="o">&</span> <span class="n">str</span> <span class="p">)</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="kt">int</span> <span class="n">compare</span><span class="p">(</span> <span class="n">string_view_type</span> <span class="n">str</span> <span class="p">)</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="kt">int</span> <span class="n">compare</span><span class="p">(</span> <span class="k">const</span> <span class="n">value_type</span><span class="o">*</span> <span class="n">s</span> <span class="p">)</span> <span class="k">const</span><span class="p">;</span>
|
|
|
|
<span class="k">template</span><span class="o"><</span> <span class="k">class</span> <span class="nc">CharT</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Traits</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">char_traits</span><span class="o"><</span><span class="n">CharT</span><span class="p">>,</span> <span class="k">class</span> <span class="nc">Alloc</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">allocator</span><span class="o"><</span><span class="n">CharT</span><span class="o">></span> <span class="o">></span>
|
|
<span class="n">std</span><span class="o">::</span><span class="n">basic_string</span><span class="o"><</span><span class="n">CharT</span><span class="p">,</span><span class="n">Traits</span><span class="p">,</span><span class="n">Alloc</span><span class="o">></span>
|
|
<span class="n">basic_string</span><span class="p">(</span> <span class="k">const</span> <span class="n">Alloc</span><span class="o">&</span> <span class="n">alloc</span> <span class="o">=</span> <span class="n">Alloc</span><span class="p">())</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">string</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="n">std</span><span class="o">::</span><span class="n">wstring</span> <span class="n">wstring</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
|
|
<span class="n">string_type</span> <span class="n">native_string</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
|
|
<span class="kt">bool</span> <span class="n">empty</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
|
|
<span class="n">key_view</span> <span class="n">key</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="n">value_view</span> <span class="n">value</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
|
|
<span class="k">friend</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o">==</span><span class="p">(</span><span class="n">key_value_pair_view</span> <span class="n">l</span><span class="p">,</span> <span class="n">key_value_pair_view</span> <span class="n">r</span><span class="p">);</span>
|
|
<span class="k">friend</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o">!=</span><span class="p">(</span><span class="n">key_value_pair_view</span> <span class="n">l</span><span class="p">,</span> <span class="n">key_value_pair_view</span> <span class="n">r</span><span class="p">);</span>
|
|
<span class="k">friend</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o"><=</span><span class="p">(</span><span class="n">key_value_pair_view</span> <span class="n">l</span><span class="p">,</span> <span class="n">key_value_pair_view</span> <span class="n">r</span><span class="p">);</span>
|
|
<span class="k">friend</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o">>=</span><span class="p">(</span><span class="n">key_value_pair_view</span> <span class="n">l</span><span class="p">,</span> <span class="n">key_value_pair_view</span> <span class="n">r</span><span class="p">);</span>
|
|
<span class="k">friend</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o"><</span> <span class="p">(</span><span class="n">key_value_pair_view</span> <span class="n">l</span><span class="p">,</span> <span class="n">key_value_pair_view</span> <span class="n">r</span><span class="p">);</span>
|
|
<span class="k">friend</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o">></span> <span class="p">(</span><span class="n">key_value_pair_view</span> <span class="n">l</span><span class="p">,</span> <span class="n">key_value_pair_view</span> <span class="n">r</span><span class="p">);</span>
|
|
|
|
|
|
<span class="k">template</span><span class="o"><</span> <span class="k">class</span> <span class="nc">CharT</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Traits</span> <span class="p">></span>
|
|
<span class="k">friend</span> <span class="n">std</span><span class="o">::</span><span class="n">basic_ostream</span><span class="o"><</span><span class="n">CharT</span><span class="p">,</span><span class="n">Traits</span><span class="o">>&</span>
|
|
<span class="k">operator</span><span class="o"><<</span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="n">basic_ostream</span><span class="o"><</span><span class="n">CharT</span><span class="p">,</span><span class="n">Traits</span><span class="o">>&</span> <span class="n">os</span><span class="p">,</span> <span class="k">const</span> <span class="n">key_value_pair_view</span><span class="o">&</span> <span class="n">p</span> <span class="p">);</span>
|
|
|
|
<span class="k">template</span><span class="o"><</span> <span class="k">class</span> <span class="nc">CharT</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Traits</span> <span class="p">></span>
|
|
<span class="k">friend</span> <span class="n">std</span><span class="o">::</span><span class="n">basic_istream</span><span class="o"><</span><span class="n">CharT</span><span class="p">,</span><span class="n">Traits</span><span class="o">>&</span>
|
|
<span class="k">operator</span><span class="o">>></span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="n">basic_istream</span><span class="o"><</span><span class="n">CharT</span><span class="p">,</span><span class="n">Traits</span><span class="o">>&</span> <span class="n">is</span><span class="p">,</span> <span class="n">key_value_pair_view</span><span class="o">&</span> <span class="n">p</span> <span class="p">);</span>
|
|
|
|
<span class="k">template</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">Idx</span><span class="p">></span>
|
|
<span class="kr">inline</span> <span class="k">auto</span> <span class="n">get</span><span class="p">()</span> <span class="k">const</span> <span class="o">-></span> <span class="k">typename</span> <span class="n">conditional</span><span class="o"><</span><span class="n">Idx</span> <span class="o">==</span> <span class="mi">0u</span><span class="p">,</span> <span class="n">key_view</span><span class="p">,</span>
|
|
<span class="n">value_view</span><span class="o">>::</span><span class="n">type</span><span class="p">;</span>
|
|
<span class="k">const</span> <span class="n">value_type</span> <span class="o">*</span> <span class="n">c_str</span><span class="p">()</span> <span class="k">const</span> <span class="k">noexcept</span><span class="p">;</span>
|
|
<span class="k">const</span> <span class="n">value_type</span> <span class="o">*</span> <span class="n">data</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">size</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
|
|
<span class="p">};</span>
|
|
|
|
<span class="c1">// Allow tuple-likg getters & structured bindings.</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="p">></span> <span class="n">key_view</span> <span class="n">key_value_pair_view</span><span class="o">::</span><span class="n">get</span><span class="o"><</span><span class="mi">0u</span><span class="o">></span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="p">></span> <span class="n">value_view</span> <span class="n">key_value_pair_view</span><span class="o">::</span><span class="n">get</span><span class="o"><</span><span class="mi">1u</span><span class="o">></span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
|
|
<span class="c1">// A class representing a key within an environment.</span>
|
|
<span class="k">struct</span> <span class="nc">key</span>
|
|
<span class="p">{</span>
|
|
<span class="k">using</span> <span class="n">value_type</span> <span class="o">=</span> <span class="n">char_type</span><span class="p">;</span>
|
|
<span class="k">using</span> <span class="n">traits_type</span> <span class="o">=</span> <span class="n">key_char_traits</span><span class="o"><</span><span class="n">char_type</span><span class="o">></span><span class="p">;</span>
|
|
<span class="k">using</span> <span class="n">string_type</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">basic_string</span><span class="o"><</span><span class="n">char_type</span><span class="p">,</span> <span class="n">traits_type</span><span class="o">></span><span class="p">;</span>
|
|
<span class="k">using</span> <span class="n">string_view_type</span> <span class="o">=</span> <span class="n">basic_string_view</span><span class="o"><</span><span class="n">char_type</span><span class="p">,</span> <span class="n">traits_type</span><span class="o">></span><span class="p">;</span>
|
|
|
|
<span class="n">key</span><span class="p">();</span>
|
|
<span class="n">key</span><span class="p">(</span> <span class="k">const</span> <span class="n">key</span><span class="o">&</span> <span class="n">p</span> <span class="p">)</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
|
|
<span class="n">key</span><span class="p">(</span> <span class="n">key</span><span class="o">&&</span> <span class="n">p</span> <span class="p">)</span> <span class="k">noexcept</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
|
|
<span class="n">key</span><span class="p">(</span> <span class="k">const</span> <span class="n">string_type</span><span class="o">&</span> <span class="n">source</span> <span class="p">);</span>
|
|
<span class="n">key</span><span class="p">(</span> <span class="n">string_type</span><span class="o">&&</span> <span class="n">source</span> <span class="p">);</span>
|
|
<span class="n">key</span><span class="p">(</span> <span class="k">const</span> <span class="n">value_type</span> <span class="o">*</span> <span class="n">raw</span> <span class="p">);</span>
|
|
<span class="n">key</span><span class="p">(</span> <span class="n">value_type</span> <span class="o">*</span> <span class="n">raw</span> <span class="p">);</span>
|
|
|
|
<span class="k">explicit</span> <span class="n">key</span><span class="p">(</span><span class="n">key_view</span> <span class="n">kv</span><span class="p">);</span>
|
|
|
|
|
|
<span class="k">template</span><span class="o"><</span> <span class="k">class</span> <span class="nc">Source</span> <span class="p">></span>
|
|
<span class="n">key</span><span class="p">(</span> <span class="k">const</span> <span class="n">Source</span><span class="o">&</span> <span class="n">source</span><span class="p">);</span>
|
|
|
|
<span class="n">key</span><span class="p">(</span><span class="k">const</span> <span class="k">typename</span> <span class="n">conditional</span><span class="o"><</span><span class="n">is_same</span><span class="o"><</span><span class="n">value_type</span><span class="p">,</span> <span class="kt">char</span><span class="o">>::</span><span class="n">value</span><span class="p">,</span> <span class="kt">wchar_t</span><span class="p">,</span> <span class="kt">char</span><span class="o">>::</span><span class="n">type</span> <span class="o">*</span> <span class="n">raw</span><span class="p">);</span>
|
|
|
|
<span class="k">template</span><span class="o"><</span> <span class="k">class</span> <span class="nc">InputIt</span> <span class="p">></span>
|
|
<span class="n">key</span><span class="p">(</span> <span class="n">InputIt</span> <span class="n">first</span><span class="p">,</span> <span class="n">InputIt</span> <span class="n">last</span><span class="p">);</span>
|
|
|
|
<span class="o">~</span><span class="n">key</span><span class="p">()</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
|
|
|
|
<span class="n">key</span><span class="o">&</span> <span class="k">operator</span><span class="o">=</span><span class="p">(</span> <span class="k">const</span> <span class="n">key</span><span class="o">&</span> <span class="n">p</span> <span class="p">)</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
|
|
<span class="n">key</span><span class="o">&</span> <span class="k">operator</span><span class="o">=</span><span class="p">(</span> <span class="n">key</span><span class="o">&&</span> <span class="n">p</span> <span class="p">);</span>
|
|
<span class="n">key</span><span class="o">&</span> <span class="k">operator</span><span class="o">=</span><span class="p">(</span> <span class="n">string_type</span><span class="o">&&</span> <span class="n">source</span> <span class="p">);</span>
|
|
|
|
<span class="k">template</span><span class="o"><</span> <span class="k">class</span> <span class="nc">Source</span> <span class="p">></span>
|
|
<span class="n">key</span><span class="o">&</span> <span class="k">operator</span><span class="o">=</span><span class="p">(</span> <span class="k">const</span> <span class="n">Source</span><span class="o">&</span> <span class="n">source</span> <span class="p">);</span>
|
|
|
|
<span class="n">key</span><span class="o">&</span> <span class="n">assign</span><span class="p">(</span> <span class="n">string_type</span><span class="o">&&</span> <span class="n">source</span> <span class="p">);</span>
|
|
|
|
<span class="k">template</span><span class="o"><</span> <span class="k">class</span> <span class="nc">Source</span> <span class="p">></span>
|
|
<span class="n">key</span><span class="o">&</span> <span class="n">assign</span><span class="p">(</span> <span class="k">const</span> <span class="n">Source</span><span class="o">&</span> <span class="n">source</span> <span class="p">);</span>
|
|
<span class="k">template</span><span class="o"><</span> <span class="k">class</span> <span class="nc">InputIt</span> <span class="p">></span>
|
|
<span class="n">key</span><span class="o">&</span> <span class="n">assign</span><span class="p">(</span> <span class="n">InputIt</span> <span class="n">first</span><span class="p">,</span> <span class="n">InputIt</span> <span class="n">last</span> <span class="p">);</span>
|
|
|
|
<span class="kt">void</span> <span class="n">clear</span><span class="p">();</span>
|
|
|
|
<span class="kt">void</span> <span class="n">swap</span><span class="p">(</span> <span class="n">key</span><span class="o">&</span> <span class="n">other</span> <span class="p">)</span> <span class="k">noexcept</span><span class="p">;</span>
|
|
|
|
<span class="k">const</span> <span class="n">value_type</span><span class="o">*</span> <span class="n">c_str</span><span class="p">()</span> <span class="k">const</span> <span class="k">noexcept</span><span class="p">;</span>
|
|
<span class="k">const</span> <span class="n">string_type</span><span class="o">&</span> <span class="n">native</span><span class="p">()</span> <span class="k">const</span> <span class="k">noexcept</span><span class="p">;</span>
|
|
<span class="n">string_view_type</span> <span class="n">native_view</span><span class="p">()</span> <span class="k">const</span> <span class="k">noexcept</span><span class="p">;</span>
|
|
|
|
<span class="k">operator</span> <span class="n">string_type</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="k">operator</span> <span class="n">string_view_type</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
|
|
<span class="kt">int</span> <span class="n">compare</span><span class="p">(</span> <span class="k">const</span> <span class="n">key</span><span class="o">&</span> <span class="n">p</span> <span class="p">)</span> <span class="k">const</span> <span class="k">noexcept</span><span class="p">;</span>
|
|
<span class="kt">int</span> <span class="n">compare</span><span class="p">(</span> <span class="k">const</span> <span class="n">string_type</span><span class="o">&</span> <span class="n">str</span> <span class="p">)</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="kt">int</span> <span class="n">compare</span><span class="p">(</span> <span class="n">string_view_type</span> <span class="n">str</span> <span class="p">)</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="kt">int</span> <span class="n">compare</span><span class="p">(</span> <span class="k">const</span> <span class="n">value_type</span><span class="o">*</span> <span class="n">s</span> <span class="p">)</span> <span class="k">const</span><span class="p">;</span>
|
|
|
|
<span class="k">template</span><span class="o"><</span> <span class="k">class</span> <span class="nc">CharT</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Traits</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">char_traits</span><span class="o"><</span><span class="n">CharT</span><span class="p">>,</span>
|
|
<span class="k">class</span> <span class="nc">Alloc</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">allocator</span><span class="o"><</span><span class="n">CharT</span><span class="o">></span> <span class="o">></span>
|
|
<span class="n">std</span><span class="o">::</span><span class="n">basic_string</span><span class="o"><</span><span class="n">CharT</span><span class="p">,</span><span class="n">Traits</span><span class="p">,</span><span class="n">Alloc</span><span class="o">></span>
|
|
<span class="n">basic_string</span><span class="p">(</span> <span class="k">const</span> <span class="n">Alloc</span><span class="o">&</span> <span class="n">alloc</span> <span class="o">=</span> <span class="n">Alloc</span><span class="p">())</span> <span class="k">const</span><span class="p">;</span>
|
|
|
|
|
|
<span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">string</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="n">std</span><span class="o">::</span><span class="n">wstring</span> <span class="n">wstring</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
|
|
<span class="k">const</span> <span class="n">string_type</span> <span class="o">&</span> <span class="n">native_string</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="kt">bool</span> <span class="n">empty</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
|
|
<span class="k">friend</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o">==</span><span class="p">(</span><span class="k">const</span> <span class="n">key</span> <span class="o">&</span> <span class="n">l</span><span class="p">,</span> <span class="k">const</span> <span class="n">key</span> <span class="o">&</span> <span class="n">r</span><span class="p">);</span>
|
|
<span class="k">friend</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o">!=</span><span class="p">(</span><span class="k">const</span> <span class="n">key</span> <span class="o">&</span> <span class="n">l</span><span class="p">,</span> <span class="k">const</span> <span class="n">key</span> <span class="o">&</span> <span class="n">r</span><span class="p">);</span>
|
|
<span class="k">friend</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o"><=</span><span class="p">(</span><span class="k">const</span> <span class="n">key</span> <span class="o">&</span> <span class="n">l</span><span class="p">,</span> <span class="k">const</span> <span class="n">key</span> <span class="o">&</span> <span class="n">r</span><span class="p">);</span>
|
|
<span class="k">friend</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o">>=</span><span class="p">(</span><span class="k">const</span> <span class="n">key</span> <span class="o">&</span> <span class="n">l</span><span class="p">,</span> <span class="k">const</span> <span class="n">key</span> <span class="o">&</span> <span class="n">r</span><span class="p">);</span>
|
|
<span class="k">friend</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o"><</span> <span class="p">(</span><span class="k">const</span> <span class="n">key</span> <span class="o">&</span> <span class="n">l</span><span class="p">,</span> <span class="k">const</span> <span class="n">key</span> <span class="o">&</span> <span class="n">r</span><span class="p">);</span>
|
|
<span class="k">friend</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o">></span> <span class="p">(</span><span class="k">const</span> <span class="n">key</span> <span class="o">&</span> <span class="n">l</span><span class="p">,</span> <span class="k">const</span> <span class="n">key</span> <span class="o">&</span> <span class="n">r</span><span class="p">);</span>
|
|
|
|
<span class="k">template</span><span class="o"><</span> <span class="k">class</span> <span class="nc">CharT</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Traits</span> <span class="p">></span>
|
|
<span class="k">friend</span> <span class="n">std</span><span class="o">::</span><span class="n">basic_ostream</span><span class="o"><</span><span class="n">CharT</span><span class="p">,</span><span class="n">Traits</span><span class="o">>&</span>
|
|
<span class="k">operator</span><span class="o"><<</span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="n">basic_ostream</span><span class="o"><</span><span class="n">CharT</span><span class="p">,</span><span class="n">Traits</span><span class="o">>&</span> <span class="n">os</span><span class="p">,</span> <span class="k">const</span> <span class="n">key</span><span class="o">&</span> <span class="n">p</span> <span class="p">);</span>
|
|
|
|
<span class="k">template</span><span class="o"><</span> <span class="k">class</span> <span class="nc">CharT</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Traits</span> <span class="p">></span>
|
|
<span class="k">friend</span> <span class="n">std</span><span class="o">::</span><span class="n">basic_istream</span><span class="o"><</span><span class="n">CharT</span><span class="p">,</span><span class="n">Traits</span><span class="o">>&</span>
|
|
<span class="k">operator</span><span class="o">>></span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="n">basic_istream</span><span class="o"><</span><span class="n">CharT</span><span class="p">,</span><span class="n">Traits</span><span class="o">>&</span> <span class="n">is</span><span class="p">,</span> <span class="n">key</span><span class="o">&</span> <span class="n">p</span> <span class="p">);</span>
|
|
<span class="k">const</span> <span class="n">value_type</span> <span class="o">*</span> <span class="n">data</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">size</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="p">};</span>
|
|
|
|
<span class="kt">bool</span> <span class="k">operator</span><span class="o">==</span><span class="p">(</span><span class="k">const</span> <span class="n">value_view</span> <span class="o">&</span><span class="p">,</span> <span class="k">const</span> <span class="n">value_view</span><span class="p">);</span>
|
|
<span class="kt">bool</span> <span class="k">operator</span><span class="o">!=</span><span class="p">(</span><span class="k">const</span> <span class="n">value_view</span> <span class="o">&</span><span class="p">,</span> <span class="k">const</span> <span class="n">value_view</span><span class="p">);</span>
|
|
<span class="kt">bool</span> <span class="k">operator</span><span class="o"><=</span><span class="p">(</span><span class="k">const</span> <span class="n">value_view</span> <span class="o">&</span><span class="p">,</span> <span class="k">const</span> <span class="n">value_view</span><span class="p">);</span>
|
|
<span class="kt">bool</span> <span class="k">operator</span><span class="o"><</span> <span class="p">(</span><span class="k">const</span> <span class="n">value_view</span> <span class="o">&</span><span class="p">,</span> <span class="k">const</span> <span class="n">value_view</span><span class="p">);</span>
|
|
<span class="kt">bool</span> <span class="k">operator</span><span class="o">></span> <span class="p">(</span><span class="k">const</span> <span class="n">value_view</span> <span class="o">&</span><span class="p">,</span> <span class="k">const</span> <span class="n">value_view</span><span class="p">);</span>
|
|
<span class="kt">bool</span> <span class="k">operator</span><span class="o">>=</span><span class="p">(</span><span class="k">const</span> <span class="n">value_view</span> <span class="o">&</span><span class="p">,</span> <span class="k">const</span> <span class="n">value_view</span><span class="p">);</span>
|
|
|
|
|
|
<span class="k">struct</span> <span class="nc">value</span>
|
|
<span class="p">{</span>
|
|
<span class="k">using</span> <span class="n">value_type</span> <span class="o">=</span> <span class="n">char_type</span><span class="p">;</span>
|
|
<span class="k">using</span> <span class="n">traits_type</span> <span class="o">=</span> <span class="n">value_char_traits</span><span class="o"><</span><span class="n">char_type</span><span class="o">></span><span class="p">;</span>
|
|
<span class="k">using</span> <span class="n">string_type</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">basic_string</span><span class="o"><</span><span class="n">char_type</span><span class="p">,</span> <span class="n">traits_type</span><span class="o">></span><span class="p">;</span>
|
|
<span class="k">using</span> <span class="n">string_view_type</span> <span class="o">=</span> <span class="n">basic_cstring_ref</span><span class="o"><</span><span class="n">char_type</span><span class="p">,</span> <span class="n">traits_type</span><span class="o">></span><span class="p">;</span>
|
|
|
|
<span class="n">value</span><span class="p">();</span>
|
|
<span class="n">value</span><span class="p">(</span> <span class="k">const</span> <span class="n">value</span><span class="o">&</span> <span class="n">p</span> <span class="p">)</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
|
|
|
|
<span class="n">value</span><span class="p">(</span> <span class="k">const</span> <span class="n">string_type</span><span class="o">&</span> <span class="n">source</span> <span class="p">);</span>
|
|
<span class="n">value</span><span class="p">(</span> <span class="n">string_type</span><span class="o">&&</span> <span class="n">source</span> <span class="p">);</span>
|
|
<span class="n">value</span><span class="p">(</span> <span class="k">const</span> <span class="n">value_type</span> <span class="o">*</span> <span class="n">raw</span> <span class="p">);</span>
|
|
<span class="n">value</span><span class="p">(</span> <span class="n">value_type</span> <span class="o">*</span> <span class="n">raw</span> <span class="p">);</span>
|
|
|
|
<span class="k">explicit</span> <span class="n">value</span><span class="p">(</span><span class="n">value_view</span> <span class="n">kv</span><span class="p">);</span>
|
|
|
|
<span class="k">template</span><span class="o"><</span> <span class="k">class</span> <span class="nc">Source</span> <span class="p">></span>
|
|
<span class="n">value</span><span class="p">(</span> <span class="k">const</span> <span class="n">Source</span><span class="o">&</span> <span class="n">source</span> <span class="p">);</span>
|
|
<span class="n">value</span><span class="p">(</span><span class="k">const</span> <span class="k">typename</span> <span class="n">conditional</span><span class="o"><</span><span class="n">is_same</span><span class="o"><</span><span class="n">value_type</span><span class="p">,</span> <span class="kt">char</span><span class="o">>::</span><span class="n">value</span><span class="p">,</span> <span class="kt">wchar_t</span><span class="p">,</span> <span class="kt">char</span><span class="o">>::</span><span class="n">type</span> <span class="o">*</span> <span class="n">raw</span><span class="p">);</span>
|
|
|
|
<span class="k">template</span><span class="o"><</span> <span class="k">class</span> <span class="nc">InputIt</span> <span class="p">></span>
|
|
<span class="n">value</span><span class="p">(</span> <span class="n">InputIt</span> <span class="n">first</span><span class="p">,</span> <span class="n">InputIt</span> <span class="n">last</span><span class="p">);</span>
|
|
|
|
<span class="o">~</span><span class="n">value</span><span class="p">()</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
|
|
|
|
<span class="n">value</span><span class="o">&</span> <span class="k">operator</span><span class="o">=</span><span class="p">(</span> <span class="k">const</span> <span class="n">value</span><span class="o">&</span> <span class="n">p</span> <span class="p">)</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
|
|
<span class="n">value</span><span class="o">&</span> <span class="k">operator</span><span class="o">=</span><span class="p">(</span> <span class="n">value</span><span class="o">&&</span> <span class="n">p</span> <span class="p">);</span>
|
|
<span class="n">value</span><span class="o">&</span> <span class="k">operator</span><span class="o">=</span><span class="p">(</span> <span class="n">string_type</span><span class="o">&&</span> <span class="n">source</span> <span class="p">);</span>
|
|
<span class="k">template</span><span class="o"><</span> <span class="k">class</span> <span class="nc">Source</span> <span class="p">></span>
|
|
<span class="n">value</span><span class="o">&</span> <span class="k">operator</span><span class="o">=</span><span class="p">(</span> <span class="k">const</span> <span class="n">Source</span><span class="o">&</span> <span class="n">source</span> <span class="p">);</span>
|
|
|
|
<span class="n">value</span><span class="o">&</span> <span class="n">assign</span><span class="p">(</span> <span class="n">string_type</span><span class="o">&&</span> <span class="n">source</span> <span class="p">);</span>
|
|
<span class="k">template</span><span class="o"><</span> <span class="k">class</span> <span class="nc">Source</span> <span class="p">></span>
|
|
<span class="n">value</span><span class="o">&</span> <span class="n">assign</span><span class="p">(</span> <span class="k">const</span> <span class="n">Source</span><span class="o">&</span> <span class="n">source</span> <span class="p">);</span>
|
|
|
|
<span class="k">template</span><span class="o"><</span> <span class="k">class</span> <span class="nc">InputIt</span> <span class="p">></span>
|
|
<span class="n">value</span><span class="o">&</span> <span class="n">assign</span><span class="p">(</span> <span class="n">InputIt</span> <span class="n">first</span><span class="p">,</span> <span class="n">InputIt</span> <span class="n">last</span> <span class="p">);</span>
|
|
|
|
<span class="kt">void</span> <span class="n">push_back</span><span class="p">(</span><span class="k">const</span> <span class="n">value</span> <span class="o">&</span> <span class="n">sv</span><span class="p">);</span>
|
|
<span class="kt">void</span> <span class="n">clear</span><span class="p">()</span> <span class="p">{</span><span class="n">value_</span><span class="p">.</span><span class="n">clear</span><span class="p">();}</span>
|
|
|
|
<span class="kt">void</span> <span class="n">swap</span><span class="p">(</span> <span class="n">value</span><span class="o">&</span> <span class="n">other</span> <span class="p">)</span> <span class="k">noexcept</span><span class="p">;</span>
|
|
|
|
<span class="k">const</span> <span class="n">value_type</span><span class="o">*</span> <span class="n">c_str</span><span class="p">()</span> <span class="k">const</span> <span class="k">noexcept</span><span class="p">;</span>
|
|
<span class="k">const</span> <span class="n">string_type</span><span class="o">&</span> <span class="n">native</span><span class="p">()</span> <span class="k">const</span> <span class="k">noexcept</span><span class="p">;</span>
|
|
<span class="n">string_view_type</span> <span class="n">native_view</span><span class="p">()</span> <span class="k">const</span> <span class="k">noexcept</span><span class="p">;</span>
|
|
|
|
<span class="k">operator</span> <span class="n">string_type</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="k">operator</span> <span class="n">string_view_type</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="k">operator</span> <span class="k">typename</span> <span class="n">string_view_type</span><span class="o">::</span><span class="n">string_view_type</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
|
|
<span class="kt">int</span> <span class="n">compare</span><span class="p">(</span> <span class="k">const</span> <span class="n">value</span><span class="o">&</span> <span class="n">p</span> <span class="p">)</span> <span class="k">const</span> <span class="k">noexcept</span><span class="p">;</span>
|
|
<span class="kt">int</span> <span class="n">compare</span><span class="p">(</span> <span class="k">const</span> <span class="n">string_type</span><span class="o">&</span> <span class="n">str</span> <span class="p">)</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="kt">int</span> <span class="n">compare</span><span class="p">(</span> <span class="n">string_view_type</span> <span class="n">str</span> <span class="p">)</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="kt">int</span> <span class="n">compare</span><span class="p">(</span> <span class="k">const</span> <span class="n">value_type</span><span class="o">*</span> <span class="n">s</span> <span class="p">)</span> <span class="k">const</span><span class="p">;</span>
|
|
|
|
<span class="k">template</span><span class="o"><</span> <span class="k">class</span> <span class="nc">CharT</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Traits</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">char_traits</span><span class="o"><</span><span class="n">CharT</span><span class="p">>,</span>
|
|
<span class="k">class</span> <span class="nc">Alloc</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">allocator</span><span class="o"><</span><span class="n">CharT</span><span class="o">></span> <span class="o">></span>
|
|
<span class="n">std</span><span class="o">::</span><span class="n">basic_string</span><span class="o"><</span><span class="n">CharT</span><span class="p">,</span><span class="n">Traits</span><span class="p">,</span><span class="n">Alloc</span><span class="o">></span>
|
|
<span class="n">basic_string</span><span class="p">(</span> <span class="k">const</span> <span class="n">Alloc</span><span class="o">&</span> <span class="n">alloc</span> <span class="o">=</span> <span class="n">Alloc</span><span class="p">())</span> <span class="k">const</span><span class="p">;</span>
|
|
|
|
<span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">string</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="n">std</span><span class="o">::</span><span class="n">wstring</span> <span class="n">wstring</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
|
|
|
|
<span class="k">const</span> <span class="n">string_type</span> <span class="o">&</span> <span class="n">native_string</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
|
|
<span class="kt">bool</span> <span class="n">empty</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
|
|
<span class="k">friend</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o">==</span><span class="p">(</span><span class="k">const</span> <span class="n">value</span> <span class="o">&</span> <span class="n">l</span><span class="p">,</span> <span class="k">const</span> <span class="n">value</span> <span class="o">&</span> <span class="n">r</span><span class="p">);</span>
|
|
<span class="k">friend</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o">!=</span><span class="p">(</span><span class="k">const</span> <span class="n">value</span> <span class="o">&</span> <span class="n">l</span><span class="p">,</span> <span class="k">const</span> <span class="n">value</span> <span class="o">&</span> <span class="n">r</span><span class="p">);</span>
|
|
<span class="k">friend</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o"><=</span><span class="p">(</span><span class="k">const</span> <span class="n">value</span> <span class="o">&</span> <span class="n">l</span><span class="p">,</span> <span class="k">const</span> <span class="n">value</span> <span class="o">&</span> <span class="n">r</span><span class="p">);</span>
|
|
<span class="k">friend</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o">>=</span><span class="p">(</span><span class="k">const</span> <span class="n">value</span> <span class="o">&</span> <span class="n">l</span><span class="p">,</span> <span class="k">const</span> <span class="n">value</span> <span class="o">&</span> <span class="n">r</span><span class="p">);</span>
|
|
<span class="k">friend</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o"><</span> <span class="p">(</span><span class="k">const</span> <span class="n">value</span> <span class="o">&</span> <span class="n">l</span><span class="p">,</span> <span class="k">const</span> <span class="n">value</span> <span class="o">&</span> <span class="n">r</span><span class="p">);</span>
|
|
<span class="k">friend</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o">></span> <span class="p">(</span><span class="k">const</span> <span class="n">value</span> <span class="o">&</span> <span class="n">l</span><span class="p">,</span> <span class="k">const</span> <span class="n">value</span> <span class="o">&</span> <span class="n">r</span><span class="p">);</span>
|
|
|
|
<span class="k">template</span><span class="o"><</span> <span class="k">class</span> <span class="nc">CharT</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Traits</span> <span class="p">></span>
|
|
<span class="k">friend</span> <span class="n">std</span><span class="o">::</span><span class="n">basic_ostream</span><span class="o"><</span><span class="n">CharT</span><span class="p">,</span><span class="n">Traits</span><span class="o">>&</span>
|
|
<span class="k">operator</span><span class="o"><<</span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="n">basic_ostream</span><span class="o"><</span><span class="n">CharT</span><span class="p">,</span><span class="n">Traits</span><span class="o">>&</span> <span class="n">os</span><span class="p">,</span> <span class="k">const</span> <span class="n">value</span><span class="o">&</span> <span class="n">p</span> <span class="p">);</span>
|
|
|
|
<span class="k">template</span><span class="o"><</span> <span class="k">class</span> <span class="nc">CharT</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Traits</span> <span class="p">></span>
|
|
<span class="k">friend</span> <span class="n">std</span><span class="o">::</span><span class="n">basic_istream</span><span class="o"><</span><span class="n">CharT</span><span class="p">,</span><span class="n">Traits</span><span class="o">>&</span>
|
|
<span class="k">operator</span><span class="o">>></span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="n">basic_istream</span><span class="o"><</span><span class="n">CharT</span><span class="p">,</span><span class="n">Traits</span><span class="o">>&</span> <span class="n">is</span><span class="p">,</span> <span class="n">value</span><span class="o">&</span> <span class="n">p</span> <span class="p">);</span>
|
|
|
|
<span class="n">value_iterator</span> <span class="n">begin</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="n">value_iterator</span> <span class="n">end</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="k">const</span> <span class="n">value_type</span> <span class="o">*</span> <span class="n">data</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">size</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="p">};</span>
|
|
|
|
|
|
<span class="kt">bool</span> <span class="k">operator</span><span class="o">==</span><span class="p">(</span><span class="k">const</span> <span class="n">value_view</span> <span class="o">&</span><span class="p">,</span> <span class="k">const</span> <span class="n">value_view</span><span class="p">);</span>
|
|
<span class="kt">bool</span> <span class="k">operator</span><span class="o">!=</span><span class="p">(</span><span class="k">const</span> <span class="n">value_view</span> <span class="o">&</span><span class="p">,</span> <span class="k">const</span> <span class="n">value_view</span><span class="p">);</span>
|
|
<span class="kt">bool</span> <span class="k">operator</span><span class="o"><=</span><span class="p">(</span><span class="k">const</span> <span class="n">value_view</span> <span class="o">&</span><span class="p">,</span> <span class="k">const</span> <span class="n">value_view</span><span class="p">);</span>
|
|
<span class="kt">bool</span> <span class="k">operator</span><span class="o"><</span> <span class="p">(</span><span class="k">const</span> <span class="n">value_view</span> <span class="o">&</span><span class="p">,</span> <span class="k">const</span> <span class="n">value_view</span><span class="p">);</span>
|
|
<span class="kt">bool</span> <span class="k">operator</span><span class="o">></span> <span class="p">(</span><span class="k">const</span> <span class="n">value_view</span> <span class="o">&</span><span class="p">,</span> <span class="k">const</span> <span class="n">value_view</span><span class="p">);</span>
|
|
<span class="kt">bool</span> <span class="k">operator</span><span class="o">>=</span><span class="p">(</span><span class="k">const</span> <span class="n">value_view</span> <span class="o">&</span><span class="p">,</span> <span class="k">const</span> <span class="n">value_view</span><span class="p">);</span>
|
|
|
|
<span class="k">struct</span> <span class="nc">key_value_pair</span>
|
|
<span class="p">{</span>
|
|
<span class="k">using</span> <span class="n">value_type</span> <span class="o">=</span> <span class="n">char_type</span><span class="p">;</span>
|
|
<span class="k">using</span> <span class="n">traits_type</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">char_traits</span><span class="o"><</span><span class="n">char_type</span><span class="o">></span><span class="p">;</span>
|
|
<span class="k">using</span> <span class="n">string_type</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">basic_string</span><span class="o"><</span><span class="n">char_type</span><span class="o">></span><span class="p">;</span>
|
|
<span class="k">using</span> <span class="n">string_view_type</span> <span class="o">=</span> <span class="n">basic_cstring_ref</span><span class="o"><</span><span class="n">char_type</span><span class="o">></span><span class="p">;</span>
|
|
|
|
<span class="n">key_value_pair</span><span class="p">()</span><span class="n">l</span>
|
|
<span class="n">key_value_pair</span><span class="p">(</span> <span class="k">const</span> <span class="n">key_value_pair</span><span class="o">&</span> <span class="n">p</span> <span class="p">)</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
|
|
<span class="n">key_value_pair</span><span class="p">(</span> <span class="n">key_value_pair</span><span class="o">&&</span> <span class="n">p</span> <span class="p">)</span> <span class="k">noexcept</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
|
|
<span class="n">key_value_pair</span><span class="p">(</span><span class="n">key_view</span> <span class="n">key</span><span class="p">,</span> <span class="n">value_view</span> <span class="n">value</span><span class="p">);</span>
|
|
|
|
<span class="n">key_value_pair</span><span class="p">(</span><span class="n">key_view</span> <span class="n">key</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">initializer_list</span><span class="o"><</span><span class="n">basic_string_view</span><span class="o"><</span><span class="n">char_type</span><span class="o">>></span> <span class="n">values</span><span class="p">);</span>
|
|
<span class="n">key_value_pair</span><span class="p">(</span> <span class="k">const</span> <span class="n">string_type</span><span class="o">&</span> <span class="n">source</span> <span class="p">);</span>
|
|
<span class="n">key_value_pair</span><span class="p">(</span> <span class="n">string_type</span><span class="o">&&</span> <span class="n">source</span> <span class="p">);</span>
|
|
<span class="n">key_value_pair</span><span class="p">(</span> <span class="k">const</span> <span class="n">value_type</span> <span class="o">*</span> <span class="n">raw</span> <span class="p">);</span>
|
|
<span class="n">key_value_pair</span><span class="p">(</span> <span class="n">value_type</span> <span class="o">*</span> <span class="n">raw</span> <span class="p">);</span>
|
|
|
|
<span class="k">explicit</span> <span class="n">key_value_pair</span><span class="p">(</span><span class="n">key_value_pair_view</span> <span class="n">kv</span><span class="p">)</span> <span class="o">:</span> <span class="n">value_</span><span class="p">(</span><span class="n">kv</span><span class="p">.</span><span class="n">c_str</span><span class="p">())</span> <span class="p">{}</span>
|
|
|
|
<span class="k">template</span><span class="o"><</span> <span class="k">class</span> <span class="nc">Source</span> <span class="p">></span>
|
|
<span class="n">key_value_pair</span><span class="p">(</span> <span class="k">const</span> <span class="n">Source</span><span class="o">&</span> <span class="n">source</span><span class="p">);</span>
|
|
|
|
<span class="k">template</span><span class="o"><</span> <span class="k">typename</span> <span class="nc">Key</span><span class="p">,</span>
|
|
<span class="k">typename</span> <span class="nc">Value</span> <span class="p">></span>
|
|
<span class="n">key_value_pair</span><span class="p">(</span>
|
|
<span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">pair</span><span class="o"><</span><span class="n">Key</span><span class="p">,</span> <span class="n">Value</span><span class="o">></span> <span class="o">&</span> <span class="n">kv</span><span class="p">);</span>
|
|
|
|
<span class="n">key_value_pair</span><span class="p">(</span><span class="k">const</span> <span class="k">typename</span> <span class="n">conditional</span><span class="o"><</span><span class="n">is_same</span><span class="o"><</span><span class="n">value_type</span><span class="p">,</span> <span class="kt">char</span><span class="o">>::</span><span class="n">value</span><span class="p">,</span> <span class="kt">wchar_t</span><span class="p">,</span> <span class="kt">char</span><span class="o">>::</span><span class="n">type</span> <span class="o">*</span> <span class="n">raw</span><span class="p">);</span>
|
|
|
|
<span class="k">template</span><span class="o"><</span> <span class="k">class</span> <span class="nc">InputIt</span> <span class="p">,</span> <span class="k">typename</span> <span class="nc">std</span><span class="o">::</span><span class="n">iterator_traits</span><span class="o"><</span><span class="n">InputIt</span><span class="p">></span><span class="o">::</span><span class="n">iterator_category</span><span class="o">></span>
|
|
<span class="n">key_value_pair</span><span class="p">(</span> <span class="n">InputIt</span> <span class="n">first</span><span class="p">,</span> <span class="n">InputIt</span> <span class="n">last</span> <span class="p">);</span>
|
|
|
|
<span class="o">~</span><span class="n">key_value_pair</span><span class="p">()</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
|
|
|
|
<span class="n">key_value_pair</span><span class="o">&</span> <span class="k">operator</span><span class="o">=</span><span class="p">(</span> <span class="k">const</span> <span class="n">key_value_pair</span><span class="o">&</span> <span class="n">p</span> <span class="p">)</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
|
|
<span class="n">key_value_pair</span><span class="o">&</span> <span class="k">operator</span><span class="o">=</span><span class="p">(</span> <span class="n">key_value_pair</span><span class="o">&&</span> <span class="n">p</span> <span class="p">);</span>
|
|
<span class="n">key_value_pair</span><span class="o">&</span> <span class="k">operator</span><span class="o">=</span><span class="p">(</span> <span class="n">string_type</span><span class="o">&&</span> <span class="n">source</span> <span class="p">);</span>
|
|
<span class="k">template</span><span class="o"><</span> <span class="k">class</span> <span class="nc">Source</span> <span class="p">></span>
|
|
<span class="n">key_value_pair</span><span class="o">&</span> <span class="k">operator</span><span class="o">=</span><span class="p">(</span> <span class="k">const</span> <span class="n">Source</span><span class="o">&</span> <span class="n">source</span> <span class="p">);</span>
|
|
|
|
<span class="n">key_value_pair</span><span class="o">&</span> <span class="n">assign</span><span class="p">(</span> <span class="n">string_type</span><span class="o">&&</span> <span class="n">source</span> <span class="p">);</span>
|
|
|
|
<span class="k">template</span><span class="o"><</span> <span class="k">class</span> <span class="nc">Source</span> <span class="p">></span>
|
|
<span class="n">key_value_pair</span><span class="o">&</span> <span class="n">assign</span><span class="p">(</span> <span class="k">const</span> <span class="n">Source</span><span class="o">&</span> <span class="n">source</span> <span class="p">);</span>
|
|
|
|
|
|
<span class="k">template</span><span class="o"><</span> <span class="k">class</span> <span class="nc">InputIt</span> <span class="p">></span>
|
|
<span class="n">key_value_pair</span><span class="o">&</span> <span class="n">assign</span><span class="p">(</span> <span class="n">InputIt</span> <span class="n">first</span><span class="p">,</span> <span class="n">InputIt</span> <span class="n">last</span> <span class="p">);</span>
|
|
|
|
<span class="kt">void</span> <span class="nf">clear</span><span class="p">();</span>
|
|
|
|
<span class="kt">void</span> <span class="n">swap</span><span class="p">(</span> <span class="n">key_value_pair</span><span class="o">&</span> <span class="n">other</span> <span class="p">)</span> <span class="k">noexcept</span><span class="p">;</span>
|
|
|
|
<span class="k">const</span> <span class="n">value_type</span><span class="o">*</span> <span class="n">c_str</span><span class="p">()</span> <span class="k">const</span> <span class="k">noexcept</span><span class="p">;</span>
|
|
<span class="k">const</span> <span class="n">string_type</span><span class="o">&</span> <span class="n">native</span><span class="p">()</span> <span class="k">const</span> <span class="k">noexcept</span><span class="p">;</span>
|
|
<span class="n">string_view_type</span> <span class="n">native_view</span><span class="p">()</span> <span class="k">const</span> <span class="k">noexcept</span><span class="p">;</span>
|
|
|
|
<span class="k">operator</span> <span class="n">string_type</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="k">operator</span> <span class="n">string_view_type</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="k">operator</span> <span class="k">typename</span> <span class="n">string_view_type</span><span class="o">::</span><span class="n">string_view_type</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="k">operator</span> <span class="n">key_value_pair_view</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
|
|
<span class="kt">int</span> <span class="n">compare</span><span class="p">(</span> <span class="k">const</span> <span class="n">key_value_pair</span><span class="o">&</span> <span class="n">p</span> <span class="p">)</span> <span class="k">const</span> <span class="k">noexcept</span><span class="p">;</span>
|
|
<span class="kt">int</span> <span class="n">compare</span><span class="p">(</span> <span class="k">const</span> <span class="n">string_type</span><span class="o">&</span> <span class="n">str</span> <span class="p">)</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="kt">int</span> <span class="n">compare</span><span class="p">(</span> <span class="n">string_view_type</span> <span class="n">str</span> <span class="p">)</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="kt">int</span> <span class="n">compare</span><span class="p">(</span> <span class="k">const</span> <span class="n">value_type</span><span class="o">*</span> <span class="n">s</span> <span class="p">)</span> <span class="k">const</span><span class="p">;</span>
|
|
|
|
<span class="k">template</span><span class="o"><</span> <span class="k">class</span> <span class="nc">CharT</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Traits</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">char_traits</span><span class="o"><</span><span class="n">CharT</span><span class="p">>,</span> <span class="k">class</span> <span class="nc">Alloc</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">allocator</span><span class="o"><</span><span class="n">CharT</span><span class="o">></span> <span class="o">></span>
|
|
<span class="n">std</span><span class="o">::</span><span class="n">basic_string</span><span class="o"><</span><span class="n">CharT</span><span class="p">,</span><span class="n">Traits</span><span class="p">,</span><span class="n">Alloc</span><span class="o">></span>
|
|
<span class="n">basic_string</span><span class="p">(</span> <span class="k">const</span> <span class="n">Alloc</span><span class="o">&</span> <span class="n">alloc</span> <span class="o">=</span> <span class="n">Alloc</span><span class="p">()</span> <span class="p">)</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="nf">string</span><span class="p">()</span> <span class="k">const</span> <span class="p">{</span><span class="k">return</span> <span class="n">basic_string</span><span class="o"><</span><span class="kt">char</span><span class="o">></span><span class="p">();}</span>
|
|
<span class="n">std</span><span class="o">::</span><span class="n">wstring</span> <span class="nf">wstring</span><span class="p">()</span> <span class="k">const</span> <span class="p">{</span><span class="k">return</span> <span class="n">basic_string</span><span class="o"><</span><span class="kt">wchar_t</span><span class="o">></span><span class="p">();}</span>
|
|
|
|
<span class="k">const</span> <span class="n">string_type</span> <span class="o">&</span> <span class="n">native_string</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="k">friend</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o">==</span><span class="p">(</span><span class="k">const</span> <span class="n">key_value_pair</span> <span class="o">&</span> <span class="n">l</span><span class="p">,</span> <span class="k">const</span> <span class="n">key_value_pair</span> <span class="o">&</span> <span class="n">r</span><span class="p">);</span>
|
|
<span class="k">friend</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o">!=</span><span class="p">(</span><span class="k">const</span> <span class="n">key_value_pair</span> <span class="o">&</span> <span class="n">l</span><span class="p">,</span> <span class="k">const</span> <span class="n">key_value_pair</span> <span class="o">&</span> <span class="n">r</span><span class="p">);</span>
|
|
<span class="k">friend</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o"><=</span><span class="p">(</span><span class="k">const</span> <span class="n">key_value_pair</span> <span class="o">&</span> <span class="n">l</span><span class="p">,</span> <span class="k">const</span> <span class="n">key_value_pair</span> <span class="o">&</span> <span class="n">r</span><span class="p">);</span>
|
|
<span class="k">friend</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o">>=</span><span class="p">(</span><span class="k">const</span> <span class="n">key_value_pair</span> <span class="o">&</span> <span class="n">l</span><span class="p">,</span> <span class="k">const</span> <span class="n">key_value_pair</span> <span class="o">&</span> <span class="n">r</span><span class="p">);</span>
|
|
<span class="k">friend</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o"><</span> <span class="p">(</span><span class="k">const</span> <span class="n">key_value_pair</span> <span class="o">&</span> <span class="n">l</span><span class="p">,</span> <span class="k">const</span> <span class="n">key_value_pair</span> <span class="o">&</span> <span class="n">r</span><span class="p">);</span>
|
|
<span class="k">friend</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o">></span> <span class="p">(</span><span class="k">const</span> <span class="n">key_value_pair</span> <span class="o">&</span> <span class="n">l</span><span class="p">,</span> <span class="k">const</span> <span class="n">key_value_pair</span> <span class="o">&</span> <span class="n">r</span><span class="p">);</span>
|
|
|
|
<span class="kt">bool</span> <span class="n">empty</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
|
|
<span class="k">struct</span> <span class="nc">key_view</span> <span class="n">key</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="k">struct</span> <span class="nc">value_view</span> <span class="n">value</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
|
|
<span class="k">template</span><span class="o"><</span> <span class="k">class</span> <span class="nc">CharT</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Traits</span> <span class="p">></span>
|
|
<span class="k">friend</span> <span class="n">std</span><span class="o">::</span><span class="n">basic_ostream</span><span class="o"><</span><span class="n">CharT</span><span class="p">,</span><span class="n">Traits</span><span class="o">>&</span>
|
|
<span class="k">operator</span><span class="o"><<</span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="n">basic_ostream</span><span class="o"><</span><span class="n">CharT</span><span class="p">,</span><span class="n">Traits</span><span class="o">>&</span> <span class="n">os</span><span class="p">,</span> <span class="k">const</span> <span class="n">key_value_pair</span><span class="o">&</span> <span class="n">p</span> <span class="p">);</span>
|
|
|
|
<span class="k">template</span><span class="o"><</span> <span class="k">class</span> <span class="nc">CharT</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Traits</span> <span class="p">></span>
|
|
<span class="k">friend</span> <span class="n">std</span><span class="o">::</span><span class="n">basic_istream</span><span class="o"><</span><span class="n">CharT</span><span class="p">,</span><span class="n">Traits</span><span class="o">>&</span>
|
|
<span class="k">operator</span><span class="o">>></span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="n">basic_istream</span><span class="o"><</span><span class="n">CharT</span><span class="p">,</span><span class="n">Traits</span><span class="o">>&</span> <span class="n">is</span><span class="p">,</span> <span class="n">key_value_pair</span><span class="o">&</span> <span class="n">p</span> <span class="p">);</span>
|
|
|
|
<span class="k">const</span> <span class="n">value_type</span> <span class="o">*</span> <span class="n">data</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">size</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
|
|
<span class="k">template</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">Idx</span><span class="p">></span>
|
|
<span class="kr">inline</span> <span class="k">auto</span> <span class="n">get</span><span class="p">()</span> <span class="k">const</span> <span class="o">-></span> <span class="k">typename</span> <span class="n">conditional</span><span class="o"><</span><span class="n">Idx</span> <span class="o">==</span> <span class="mi">0u</span><span class="p">,</span><span class="n">environment</span><span class="o">::</span><span class="n">key_view</span><span class="p">,</span> <span class="n">environment</span><span class="o">::</span><span class="n">value_view</span><span class="o">>::</span><span class="n">type</span><span class="p">;</span>
|
|
<span class="p">};</span>
|
|
|
|
<span class="kt">bool</span> <span class="k">operator</span><span class="o">==</span><span class="p">(</span><span class="k">const</span> <span class="n">key_value_pair_view</span> <span class="o">&</span><span class="p">,</span> <span class="k">const</span> <span class="n">key_value_pair_view</span><span class="p">);</span>
|
|
<span class="kt">bool</span> <span class="k">operator</span><span class="o">!=</span><span class="p">(</span><span class="k">const</span> <span class="n">key_value_pair_view</span> <span class="o">&</span><span class="p">,</span> <span class="k">const</span> <span class="n">key_value_pair_view</span><span class="p">);</span>
|
|
<span class="kt">bool</span> <span class="k">operator</span><span class="o"><=</span><span class="p">(</span><span class="k">const</span> <span class="n">key_value_pair_view</span> <span class="o">&</span><span class="p">,</span> <span class="k">const</span> <span class="n">key_value_pair_view</span><span class="p">);</span>
|
|
<span class="kt">bool</span> <span class="k">operator</span><span class="o"><</span> <span class="p">(</span><span class="k">const</span> <span class="n">key_value_pair_view</span> <span class="o">&</span><span class="p">,</span> <span class="k">const</span> <span class="n">key_value_pair_view</span><span class="p">);</span>
|
|
<span class="kt">bool</span> <span class="k">operator</span><span class="o">></span> <span class="p">(</span><span class="k">const</span> <span class="n">key_value_pair_view</span> <span class="o">&</span><span class="p">,</span> <span class="k">const</span> <span class="n">key_value_pair_view</span><span class="p">);</span>
|
|
<span class="kt">bool</span> <span class="k">operator</span><span class="o">>=</span><span class="p">(</span><span class="k">const</span> <span class="n">key_value_pair_view</span> <span class="o">&</span><span class="p">,</span> <span class="k">const</span> <span class="n">key_value_pair_view</span><span class="p">);</span>
|
|
|
|
|
|
<span class="c1">// Allow tuple-likg getters & structured bindings.</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="p">></span>
|
|
<span class="n">key_view</span> <span class="n">key_value_pair</span><span class="o">::</span><span class="n">get</span><span class="o"><</span><span class="mi">0u</span><span class="o">></span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
|
|
<span class="k">template</span><span class="o"><</span><span class="p">></span>
|
|
<span class="n">value_view</span> <span class="n">key_value_pair</span><span class="o">::</span><span class="n">get</span><span class="o"><</span><span class="mi">1u</span><span class="o">></span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
|
|
<span class="c1">// A view object for the current environment of this process.</span>
|
|
<span class="cm">/*
|
|
* The view might (windows) or might not (posix) be owning;
|
|
* if it owns it will deallocate the on destruction, like a unique_ptr.
|
|
*
|
|
* Note that accessing the environment in this way is not thread-safe.
|
|
*
|
|
* @code
|
|
*
|
|
* void dump_my_env(current_view env = current())
|
|
* {
|
|
* for (auto & [k, v] : env)
|
|
* std::cout << k.string() << " = " << v.string() << std::endl;
|
|
* }
|
|
*
|
|
* @endcode
|
|
*
|
|
*
|
|
*/</span>
|
|
<span class="k">struct</span> <span class="nc">current_view</span>
|
|
<span class="p">{</span>
|
|
<span class="k">using</span> <span class="n">native_handle_type</span> <span class="o">=</span> <span class="n">environment</span><span class="o">::</span><span class="n">native_handle_type</span><span class="p">;</span>
|
|
<span class="k">using</span> <span class="n">value_type</span> <span class="o">=</span> <span class="n">key_value_pair_view</span><span class="p">;</span>
|
|
|
|
<span class="n">current_view</span><span class="p">()</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
|
|
<span class="n">current_view</span><span class="p">(</span><span class="n">current_view</span> <span class="o">&&</span> <span class="n">nt</span><span class="p">)</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
|
|
|
|
<span class="n">native_handle_type</span> <span class="n">native_handle</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="n">handle_</span><span class="p">.</span><span class="n">get</span><span class="p">();</span> <span class="p">}</span>
|
|
|
|
<span class="k">struct</span> <span class="nc">iterator</span>
|
|
<span class="p">{</span>
|
|
<span class="k">using</span> <span class="n">value_type</span> <span class="o">=</span> <span class="n">key_value_pair_view</span><span class="p">;</span>
|
|
<span class="k">using</span> <span class="n">difference_type</span> <span class="o">=</span> <span class="kt">int</span><span class="p">;</span>
|
|
<span class="k">using</span> <span class="n">reference</span> <span class="o">=</span> <span class="n">key_value_pair_view</span><span class="p">;</span>
|
|
<span class="k">using</span> <span class="n">pointer</span> <span class="o">=</span> <span class="n">key_value_pair_view</span><span class="p">;</span>
|
|
<span class="k">using</span> <span class="n">iterator_category</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">forward_iterator_tag</span><span class="p">;</span>
|
|
|
|
<span class="n">iterator</span><span class="p">()</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
|
|
<span class="n">iterator</span><span class="p">(</span><span class="k">const</span> <span class="n">iterator</span> <span class="o">&</span> <span class="p">)</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
|
|
<span class="n">iterator</span><span class="p">(</span><span class="k">const</span> <span class="n">native_iterator</span> <span class="o">&</span><span class="n">native_handle</span><span class="p">)</span> <span class="o">:</span> <span class="n">iterator_</span><span class="p">(</span><span class="n">native_handle</span><span class="p">)</span> <span class="p">{}</span>
|
|
|
|
<span class="n">iterator</span> <span class="o">&</span> <span class="k">operator</span><span class="o">++</span><span class="p">()</span>
|
|
<span class="p">{</span>
|
|
<span class="n">iterator_</span> <span class="o">=</span> <span class="n">detail</span><span class="o">::</span><span class="n">next</span><span class="p">(</span><span class="n">iterator_</span><span class="p">);</span>
|
|
<span class="k">return</span> <span class="o">*</span><span class="k">this</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="n">iterator</span> <span class="k">operator</span><span class="o">++</span><span class="p">(</span><span class="kt">int</span><span class="p">)</span>
|
|
<span class="p">{</span>
|
|
<span class="k">auto</span> <span class="n">last</span> <span class="o">=</span> <span class="o">*</span><span class="k">this</span><span class="p">;</span>
|
|
<span class="n">iterator_</span> <span class="o">=</span> <span class="n">detail</span><span class="o">::</span><span class="n">next</span><span class="p">(</span><span class="n">iterator_</span><span class="p">);</span>
|
|
<span class="k">return</span> <span class="n">last</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="n">key_value_pair_view</span> <span class="k">operator</span><span class="o">*</span><span class="p">()</span> <span class="k">const</span>
|
|
<span class="p">{</span>
|
|
<span class="k">return</span> <span class="n">detail</span><span class="o">::</span><span class="n">dereference</span><span class="p">(</span><span class="n">iterator_</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="k">friend</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o">==</span><span class="p">(</span><span class="k">const</span> <span class="n">iterator</span> <span class="o">&</span> <span class="n">l</span><span class="p">,</span> <span class="k">const</span> <span class="n">iterator</span> <span class="o">&</span> <span class="n">r</span><span class="p">)</span> <span class="p">{</span><span class="k">return</span> <span class="n">l</span><span class="p">.</span><span class="n">iterator_</span> <span class="o">==</span> <span class="n">r</span><span class="p">.</span><span class="n">iterator_</span><span class="p">;}</span>
|
|
<span class="k">friend</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o">!=</span><span class="p">(</span><span class="k">const</span> <span class="n">iterator</span> <span class="o">&</span> <span class="n">l</span><span class="p">,</span> <span class="k">const</span> <span class="n">iterator</span> <span class="o">&</span> <span class="n">r</span><span class="p">)</span> <span class="p">{</span><span class="k">return</span> <span class="n">l</span><span class="p">.</span><span class="n">iterator_</span> <span class="o">!=</span> <span class="n">r</span><span class="p">.</span><span class="n">iterator_</span><span class="p">;}</span>
|
|
|
|
<span class="k">private</span><span class="o">:</span>
|
|
<span class="n">environment</span><span class="o">::</span><span class="n">native_iterator</span> <span class="n">iterator_</span><span class="p">;</span>
|
|
<span class="p">};</span>
|
|
|
|
<span class="n">iterator</span> <span class="nf">begin</span><span class="p">()</span> <span class="k">const</span> <span class="p">{</span><span class="k">return</span> <span class="n">iterator</span><span class="p">(</span><span class="n">handle_</span><span class="p">.</span><span class="n">get</span><span class="p">());}</span>
|
|
<span class="n">iterator</span> <span class="nf">end</span><span class="p">()</span> <span class="k">const</span> <span class="p">{</span><span class="k">return</span> <span class="n">iterator</span><span class="p">(</span><span class="n">detail</span><span class="o">::</span><span class="n">find_end</span><span class="p">(</span><span class="n">handle_</span><span class="p">.</span><span class="n">get</span><span class="p">()));}</span>
|
|
|
|
<span class="k">private</span><span class="o">:</span>
|
|
|
|
<span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="k">typename</span> <span class="n">remove_pointer</span><span class="o"><</span><span class="n">native_handle_type</span><span class="o">>::</span><span class="n">type</span><span class="p">,</span>
|
|
<span class="n">detail</span><span class="o">::</span><span class="n">native_handle_deleter</span><span class="o">></span> <span class="n">handle_</span><span class="p">{</span><span class="n">environment</span><span class="o">::</span><span class="n">detail</span><span class="o">::</span><span class="n">load_native_handle</span><span class="p">()};</span>
|
|
<span class="p">};</span>
|
|
|
|
<span class="c1">// Obtain a handle to the current environment</span>
|
|
<span class="kr">inline</span> <span class="n">current_view</span> <span class="nf">current</span><span class="p">()</span> <span class="p">{</span><span class="k">return</span> <span class="n">current_view</span><span class="p">();}</span>
|
|
|
|
<span class="c1">// Find the home folder in an environment-like type.</span>
|
|
<span class="cm">/*
|
|
* @param env The environment to search. Defaults to the current environment of this process
|
|
*
|
|
* The environment type passed in must be a range with value T that fulfills the following requirements:
|
|
*
|
|
* For `T value`
|
|
*
|
|
* - std::get<0>(value) must return a type comparable to `key_view`.
|
|
* - std::get<1>(value) must return a type convertible to filesystem::path.
|
|
*
|
|
* @return A filesystem::path to the home directory or an empty path if it cannot be found.
|
|
*
|
|
*/</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Environment</span> <span class="o">=</span> <span class="n">current_view</span><span class="p">></span>
|
|
<span class="kr">inline</span> <span class="n">filesystem</span><span class="o">::</span><span class="n">path</span> <span class="nf">home</span><span class="p">(</span><span class="n">Environment</span> <span class="o">&&</span> <span class="n">env</span> <span class="o">=</span> <span class="n">current</span><span class="p">());</span>
|
|
|
|
<span class="c1">// Find the executable `name` in an environment-like type.</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Environment</span> <span class="o">=</span> <span class="n">current_view</span><span class="p">></span>
|
|
<span class="n">filesystem</span><span class="o">::</span><span class="n">path</span> <span class="nf">find_executable</span><span class="p">(</span><span class="n">BOOST_PROCESS_V2_NAMESPACE</span><span class="o">::</span><span class="n">filesystem</span><span class="o">::</span><span class="n">path</span> <span class="n">name</span><span class="p">,</span>
|
|
<span class="n">Environment</span> <span class="o">&&</span> <span class="n">env</span> <span class="o">=</span> <span class="n">current</span><span class="p">());</span>
|
|
|
|
<span class="c1">// Get an environment variable from the current process.</span>
|
|
<span class="n">value</span> <span class="nf">get</span><span class="p">(</span><span class="k">const</span> <span class="n">key</span> <span class="o">&</span> <span class="n">k</span><span class="p">,</span> <span class="n">error_code</span> <span class="o">&</span> <span class="n">ec</span><span class="p">);</span>
|
|
<span class="n">value</span> <span class="nf">get</span><span class="p">(</span><span class="k">const</span> <span class="n">key</span> <span class="o">&</span> <span class="n">k</span><span class="p">);</span>
|
|
<span class="n">value</span> <span class="nf">get</span><span class="p">(</span><span class="n">basic_cstring_ref</span><span class="o"><</span><span class="n">char_type</span><span class="p">,</span> <span class="n">key_char_traits</span><span class="o"><</span><span class="n">char_type</span><span class="o">>></span> <span class="n">k</span><span class="p">,</span> <span class="n">error_code</span> <span class="o">&</span> <span class="n">ec</span><span class="p">);</span>
|
|
<span class="n">value</span> <span class="nf">get</span><span class="p">(</span><span class="n">basic_cstring_ref</span><span class="o"><</span><span class="n">char_type</span><span class="p">,</span> <span class="n">key_char_traits</span><span class="o"><</span><span class="n">char_type</span><span class="o">>></span> <span class="n">k</span><span class="p">);</span>
|
|
<span class="n">value</span> <span class="nf">get</span><span class="p">(</span><span class="k">const</span> <span class="n">char_type</span> <span class="o">*</span> <span class="n">c</span><span class="p">,</span> <span class="n">error_code</span> <span class="o">&</span> <span class="n">ec</span><span class="p">);</span>
|
|
<span class="n">value</span> <span class="nf">get</span><span class="p">(</span><span class="k">const</span> <span class="n">char_type</span> <span class="o">*</span> <span class="n">c</span><span class="p">);</span>
|
|
|
|
<span class="c1">// Set an environment variable for the current process.</span>
|
|
<span class="kt">void</span> <span class="nf">set</span><span class="p">(</span><span class="k">const</span> <span class="n">key</span> <span class="o">&</span> <span class="n">k</span><span class="p">,</span> <span class="n">value_view</span> <span class="n">vw</span><span class="p">,</span> <span class="n">error_code</span> <span class="o">&</span> <span class="n">ec</span><span class="p">);</span>
|
|
<span class="kt">void</span> <span class="nf">set</span><span class="p">(</span><span class="k">const</span> <span class="n">key</span> <span class="o">&</span> <span class="n">k</span><span class="p">,</span> <span class="n">value_view</span> <span class="n">vw</span><span class="p">);</span>
|
|
<span class="kt">void</span> <span class="nf">set</span><span class="p">(</span><span class="n">basic_cstring_ref</span><span class="o"><</span><span class="n">char_type</span><span class="p">,</span> <span class="n">key_char_traits</span><span class="o"><</span><span class="n">char_type</span><span class="o">>></span> <span class="n">k</span><span class="p">,</span> <span class="n">value_view</span> <span class="n">vw</span><span class="p">,</span> <span class="n">error_code</span> <span class="o">&</span> <span class="n">ec</span><span class="p">);</span>
|
|
<span class="kt">void</span> <span class="nf">set</span><span class="p">(</span><span class="n">basic_cstring_ref</span><span class="o"><</span><span class="n">char_type</span><span class="p">,</span> <span class="n">key_char_traits</span><span class="o"><</span><span class="n">char_type</span><span class="o">>></span> <span class="n">k</span><span class="p">,</span> <span class="n">value_view</span> <span class="n">vw</span><span class="p">);</span>
|
|
<span class="kt">void</span> <span class="nf">set</span><span class="p">(</span><span class="k">const</span> <span class="n">char_type</span> <span class="o">*</span> <span class="n">k</span><span class="p">,</span> <span class="n">value_view</span> <span class="n">vw</span><span class="p">,</span> <span class="n">error_code</span> <span class="o">&</span> <span class="n">ec</span><span class="p">);</span>
|
|
<span class="kt">void</span> <span class="nf">set</span><span class="p">(</span><span class="k">const</span> <span class="n">char_type</span> <span class="o">*</span> <span class="n">k</span><span class="p">,</span> <span class="n">value_view</span> <span class="n">vw</span><span class="p">);</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Char</span><span class="p">></span>
|
|
<span class="kt">void</span> <span class="nf">set</span><span class="p">(</span><span class="k">const</span> <span class="n">key</span> <span class="o">&</span> <span class="n">k</span><span class="p">,</span> <span class="k">const</span> <span class="n">Char</span> <span class="o">*</span> <span class="n">vw</span><span class="p">,</span> <span class="n">error_code</span> <span class="o">&</span> <span class="n">ec</span><span class="p">);</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Char</span><span class="p">></span>
|
|
<span class="kt">void</span> <span class="nf">set</span><span class="p">(</span><span class="k">const</span> <span class="n">key</span> <span class="o">&</span> <span class="n">k</span><span class="p">,</span> <span class="k">const</span> <span class="n">Char</span> <span class="o">*</span> <span class="n">vw</span><span class="p">);</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Char</span><span class="p">></span>
|
|
<span class="kt">void</span> <span class="nf">set</span><span class="p">(</span><span class="n">basic_cstring_ref</span><span class="o"><</span><span class="n">char_type</span><span class="p">,</span> <span class="n">key_char_traits</span><span class="o"><</span><span class="n">char_type</span><span class="o">>></span> <span class="n">k</span><span class="p">,</span> <span class="k">const</span> <span class="n">Char</span> <span class="o">*</span> <span class="n">vw</span><span class="p">,</span> <span class="n">error_code</span> <span class="o">&</span> <span class="n">ec</span><span class="p">);</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Char</span><span class="p">></span>
|
|
<span class="kt">void</span> <span class="nf">set</span><span class="p">(</span><span class="n">basic_cstring_ref</span><span class="o"><</span><span class="n">char_type</span><span class="p">,</span> <span class="n">key_char_traits</span><span class="o"><</span><span class="n">char_type</span><span class="o">>></span> <span class="n">k</span><span class="p">,</span> <span class="k">const</span> <span class="n">Char</span> <span class="o">*</span> <span class="n">vw</span><span class="p">);</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Char</span><span class="p">></span>
|
|
<span class="kt">void</span> <span class="nf">set</span><span class="p">(</span><span class="k">const</span> <span class="n">char_type</span> <span class="o">*</span> <span class="n">k</span><span class="p">,</span> <span class="k">const</span> <span class="n">Char</span> <span class="o">*</span> <span class="n">vw</span><span class="p">,</span> <span class="n">error_code</span> <span class="o">&</span> <span class="n">ec</span><span class="p">);</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Char</span><span class="p">></span>
|
|
<span class="kt">void</span> <span class="nf">set</span><span class="p">(</span><span class="k">const</span> <span class="n">char_type</span> <span class="o">*</span> <span class="n">k</span><span class="p">,</span> <span class="k">const</span> <span class="n">Char</span> <span class="o">*</span> <span class="n">vw</span><span class="p">);</span>
|
|
|
|
<span class="c1">// Remove an environment variable from the current process.</span>
|
|
<span class="kt">void</span> <span class="nf">unset</span><span class="p">(</span><span class="k">const</span> <span class="n">key</span> <span class="o">&</span> <span class="n">k</span><span class="p">,</span> <span class="n">error_code</span> <span class="o">&</span> <span class="n">ec</span><span class="p">);</span>
|
|
<span class="kt">void</span> <span class="nf">unset</span><span class="p">(</span><span class="k">const</span> <span class="n">key</span> <span class="o">&</span> <span class="n">k</span><span class="p">);</span>
|
|
<span class="kt">void</span> <span class="nf">unset</span><span class="p">(</span><span class="n">basic_cstring_ref</span><span class="o"><</span><span class="n">char_type</span><span class="p">,</span> <span class="n">key_char_traits</span><span class="o"><</span><span class="n">char_type</span><span class="o">>></span> <span class="n">k</span><span class="p">,</span> <span class="n">error_code</span> <span class="o">&</span> <span class="n">ec</span><span class="p">);</span>
|
|
<span class="kt">void</span> <span class="nf">unset</span><span class="p">(</span><span class="n">basic_cstring_ref</span><span class="o"><</span><span class="n">char_type</span><span class="p">,</span> <span class="n">key_char_traits</span><span class="o"><</span><span class="n">char_type</span><span class="o">>></span> <span class="n">k</span><span class="p">);</span>
|
|
<span class="kt">void</span> <span class="nf">unset</span><span class="p">(</span><span class="k">const</span> <span class="n">char_type</span> <span class="o">*</span> <span class="n">c</span><span class="p">,</span> <span class="n">error_code</span> <span class="o">&</span> <span class="n">ec</span><span class="p">);</span>
|
|
<span class="kt">void</span> <span class="nf">unset</span><span class="p">(</span><span class="k">const</span> <span class="n">char_type</span> <span class="o">*</span> <span class="n">c</span><span class="p">);</span>
|
|
|
|
<span class="p">}</span></code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect3">
|
|
<h4 id="process_environment"><code>process_environment</code></h4>
|
|
<div class="paragraph">
|
|
<p>In order to set the environment of a child process, <code>process_environment</code> can be used.</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="title">This will set the environment in a subprocess:</div>
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"><span class="n">process</span> <span class="n">proc</span><span class="p">{</span><span class="n">executor</span><span class="p">,</span> <span class="n">find_executable</span><span class="p">(</span><span class="s">"printenv"</span><span class="p">),</span> <span class="p">{</span><span class="s">"foo"</span><span class="p">},</span> <span class="n">process_environment</span><span class="p">{</span><span class="s">"foo=bar"</span><span class="p">}};</span></code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The environment initializer will persist it’s state, so that it can
|
|
be used multiple times. Do however note the the Operating System is
|
|
allowed to modify the internal state.</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"><span class="k">auto</span> <span class="n">exe</span> <span class="o">=</span> <span class="n">find_executable</span><span class="p">(</span><span class="s">"printenv"</span><span class="p">);</span>
|
|
<span class="n">process_environment</span> <span class="n">env</span> <span class="o">=</span> <span class="p">{</span><span class="s">"FOO=BAR"</span><span class="p">,</span> <span class="s">"BAR=FOO"</span><span class="p">};</span>
|
|
|
|
<span class="n">process</span> <span class="nf">proc1</span><span class="p">(</span><span class="n">executor</span><span class="p">,</span> <span class="n">exe</span><span class="p">,</span> <span class="p">{</span><span class="s">"FOO"</span><span class="p">},</span> <span class="n">env</span><span class="p">);</span>
|
|
<span class="n">process</span> <span class="nf">proc2</span><span class="p">(</span><span class="n">executor</span><span class="p">,</span> <span class="n">exe</span><span class="p">,</span> <span class="p">{</span><span class="s">"BAR"</span><span class="p">},</span> <span class="n">env</span><span class="p">);</span></code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="error_hpp"><code>error.hpp</code></h3>
|
|
<div id="error" class="paragraph">
|
|
<p>The error header provides two error categories:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"><span class="c1">// Errors used for utf8 <-> UCS-2 conversions.</span>
|
|
<span class="k">enum</span> <span class="n">utf8_conv_error</span>
|
|
<span class="p">{</span>
|
|
<span class="n">insufficient_buffer</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span>
|
|
<span class="n">invalid_character</span><span class="p">,</span>
|
|
<span class="p">};</span>
|
|
|
|
<span class="k">extern</span> <span class="k">const</span> <span class="n">error_category</span><span class="o">&</span> <span class="n">get_utf8_category</span><span class="p">();</span>
|
|
<span class="k">static</span> <span class="k">const</span> <span class="n">error_category</span><span class="o">&</span> <span class="n">utf8_category</span> <span class="o">=</span> <span class="n">get_utf8_category</span><span class="p">();</span>
|
|
|
|
<span class="k">extern</span> <span class="k">const</span> <span class="n">error_category</span><span class="o">&</span> <span class="n">get_exit_code_category</span><span class="p">();</span>
|
|
|
|
<span class="c1">/// An error category that can be used to interpret exit codes of subprocesses.</span>
|
|
<span class="k">static</span> <span class="k">const</span> <span class="n">error_category</span><span class="o">&</span> <span class="n">exit_code_category</span> <span class="o">=</span> <span class="n">get_exit_code_category</span><span class="p">();</span>
|
|
|
|
<span class="p">}</span></code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The <code>get_exit_code_category</code> can be used as follows:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"><span class="kt">void</span> <span class="nf">run_my_process</span><span class="p">(</span><span class="n">filesystem</span><span class="o">::</span><span class="n">path</span> <span class="n">pt</span><span class="p">,</span> <span class="n">error_code</span> <span class="o">&</span> <span class="n">ec</span><span class="p">)</span>
|
|
<span class="p">{</span>
|
|
<span class="n">process</span> <span class="n">proc</span><span class="p">(</span><span class="n">pt</span><span class="p">,</span> <span class="p">{});</span>
|
|
<span class="n">proc</span><span class="p">.</span><span class="n">wait</span><span class="p">();</span>
|
|
<span class="n">ec</span><span class="p">.</span><span class="n">assign</span><span class="p">(</span><span class="n">proc</span><span class="p">.</span><span class="n">native_exit_code</span><span class="p">(),</span> <span class="n">error</span><span class="o">::</span><span class="n">get_exit_code_category</span><span class="p">());</span>
|
|
<span class="p">}</span></code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="execute_hpp"><code>execute.hpp</code></h3>
|
|
<div id="execute" class="paragraph">
|
|
<p>The execute header provides two error categories:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"><span class="c1">// Run a process and wait for it to complete.</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Executor</span><span class="p">></span> <span class="kt">int</span> <span class="nf">execute</span><span class="p">(</span><span class="n">basic_process</span><span class="o"><</span><span class="n">Executor</span><span class="o">></span> <span class="n">proc</span><span class="p">);</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Executor</span><span class="p">></span> <span class="kt">int</span> <span class="nf">execute</span><span class="p">(</span><span class="n">basic_process</span><span class="o"><</span><span class="n">Executor</span><span class="o">></span> <span class="n">proc</span><span class="p">,</span> <span class="n">error_code</span> <span class="o">&</span> <span class="n">ec</span><span class="p">)</span>
|
|
|
|
<span class="c1">// Execute a process asynchronously</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Executor</span> <span class="o">=</span> <span class="n">net</span><span class="o">::</span><span class="n">any_io_executor</span><span class="p">,</span>
|
|
<span class="n">BOOST_PROCESS_V2_COMPLETION_TOKEN_FOR</span><span class="p">(</span><span class="kt">void</span> <span class="p">(</span><span class="n">error_code</span><span class="p">,</span> <span class="kt">int</span><span class="p">))</span>
|
|
<span class="n">WaitHandler</span> <span class="o">=</span> <span class="n">net</span><span class="o">::</span><span class="n">default_completion_token_t</span><span class="o"><</span><span class="n">Executor</span><span class="p">></span><span class="o">></span>
|
|
<span class="k">auto</span> <span class="n">async_execute</span><span class="p">(</span><span class="n">basic_process</span><span class="o"><</span><span class="n">Executor</span><span class="o">></span> <span class="n">proc</span><span class="p">,</span>
|
|
<span class="n">WaitHandler</span> <span class="o">&&</span> <span class="n">handler</span> <span class="o">=</span> <span class="n">net</span><span class="o">::</span><span class="n">default_completion_token_t</span><span class="o"><</span><span class="n">Executor</span><span class="o">></span><span class="p">());</span></code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The <code>async_execute</code> function asynchronously for a process to complete.</p>
|
|
</div>
|
|
<div class="literalblock">
|
|
<div class="content">
|
|
<pre>Cancelling the execution will signal the child process to exit
|
|
with the following interpretations:</pre>
|
|
</div>
|
|
</div>
|
|
<div class="ulist">
|
|
<ul>
|
|
<li>
|
|
<p><code>cancellation_type::total</code> → interrupt</p>
|
|
</li>
|
|
<li>
|
|
<p><code>cancellation_type::partial</code> → request_exit</p>
|
|
</li>
|
|
<li>
|
|
<p><code>cancellation_type::terminal</code> → terminate</p>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>It is to note that <code>async_execute</code> will use the lowest selected cancellation
|
|
type. A subprocess might ignore anything not terminal.</p>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="exit_code_hpp"><code>exit_code.hpp</code></h3>
|
|
<div id="exit_code" class="paragraph">
|
|
<p>The exit code header provides portable handles for exit codes.</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"><span class="c1">// The native exit-code type, usually an integral value</span>
|
|
<span class="cm">/* The OS may have a value different from `int` to represent
|
|
* the exit codes of subprocesses. It might also
|
|
* contain additional information.
|
|
*/</span>
|
|
<span class="k">typedef</span> <span class="n">implementation_defined</span> <span class="n">native_exit_code_type</span><span class="p">;</span>
|
|
|
|
|
|
<span class="c1">// Check if the native exit code indicates the process is still running</span>
|
|
<span class="kt">bool</span> <span class="nf">process_is_running</span><span class="p">(</span><span class="n">native_exit_code_type</span> <span class="n">code</span><span class="p">);</span>
|
|
|
|
<span class="c1">// Obtain the portable part of the exit code, i.e. what the subprocess has returned from main.</span>
|
|
<span class="kt">int</span> <span class="nf">evaluate_exit_code</span><span class="p">(</span><span class="n">native_exit_code_type</span> <span class="n">code</span><span class="p">);</span>
|
|
|
|
<span class="c1">// Helper to subsume an exit-code into an error_code if there's no actual error isn't set.</span>
|
|
<span class="n">error_code</span> <span class="nf">check_exit_code</span><span class="p">(</span>
|
|
<span class="n">error_code</span> <span class="o">&</span><span class="n">ec</span><span class="p">,</span> <span class="n">native_exit_code_type</span> <span class="n">native_code</span><span class="p">,</span>
|
|
<span class="k">const</span> <span class="n">error_category</span> <span class="o">&</span> <span class="n">category</span> <span class="o">=</span> <span class="n">error</span><span class="o">::</span><span class="n">get_exit_code_category</span><span class="p">());</span></code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The <code>check_exit_code</code> can be used like this:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"><span class="n">process</span> <span class="n">proc</span><span class="p">{</span><span class="k">co_await</span> <span class="n">this_coro</span><span class="o">::</span><span class="n">executor</span><span class="p">,</span> <span class="s">"exit"</span><span class="p">,</span> <span class="p">{</span><span class="s">"1"</span><span class="p">}};</span>
|
|
|
|
<span class="k">co_await</span> <span class="n">proc</span><span class="p">.</span><span class="n">async_wait</span><span class="p">(</span>
|
|
<span class="n">asio</span><span class="o">::</span><span class="n">deferred</span><span class="p">(</span>
|
|
<span class="p">[</span><span class="o">&</span><span class="n">proc</span><span class="p">](</span><span class="n">error_code</span> <span class="n">ec</span><span class="p">,</span> <span class="kt">int</span><span class="p">)</span>
|
|
<span class="p">{</span>
|
|
<span class="k">return</span> <span class="n">asio</span><span class="o">::</span><span class="n">deferred</span><span class="p">.</span><span class="n">values</span><span class="p">(</span>
|
|
<span class="n">check_exit_code</span><span class="p">(</span><span class="n">ec</span><span class="p">,</span> <span class="n">proc</span><span class="p">.</span><span class="n">native_exit_code</span><span class="p">())</span>
|
|
<span class="p">);</span></code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="ext"><code>ext</code></h3>
|
|
<div class="paragraph">
|
|
<p>The headers in <code>process/ext</code> provides features to obtain information about third part processes.</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"><span class="c1">// Get the cmd line used to launche the process</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Executor</span><span class="p">></span>
|
|
<span class="n">shell</span> <span class="nf">cmd</span><span class="p">(</span><span class="n">basic_process_handle</span><span class="o"><</span><span class="n">Executor</span><span class="o">></span> <span class="o">&</span> <span class="n">handle</span><span class="p">,</span> <span class="n">error_code</span> <span class="o">&</span> <span class="n">ec</span><span class="p">);</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Executor</span><span class="p">></span>
|
|
<span class="n">shell</span> <span class="nf">cmd</span><span class="p">(</span><span class="n">basic_process_handle</span><span class="o"><</span><span class="n">Executor</span><span class="o">></span> <span class="o">&</span> <span class="n">handle</span><span class="p">);</span>
|
|
<span class="n">shell</span> <span class="nf">cmd</span><span class="p">(</span><span class="n">pid_type</span> <span class="n">pid</span><span class="p">,</span> <span class="n">error_code</span> <span class="o">&</span> <span class="n">ec</span><span class="p">);</span>
|
|
<span class="n">shell</span> <span class="nf">cmd</span><span class="p">(</span><span class="n">pid_type</span> <span class="n">pid</span><span class="p">);</span>
|
|
|
|
|
|
<span class="c1">// Get the current working directory of the process.</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Executor</span><span class="p">></span>
|
|
<span class="n">filesystem</span><span class="o">::</span><span class="n">path</span> <span class="nf">cwd</span><span class="p">(</span><span class="n">basic_process_handle</span><span class="o"><</span><span class="n">Executor</span><span class="o">></span> <span class="o">&</span> <span class="n">handle</span><span class="p">,</span> <span class="n">error_code</span> <span class="o">&</span> <span class="n">ec</span><span class="p">);</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Executor</span><span class="p">></span>
|
|
<span class="n">filesystem</span><span class="o">::</span><span class="n">path</span> <span class="nf">cwd</span><span class="p">(</span><span class="n">basic_process_handle</span><span class="o"><</span><span class="n">Executor</span><span class="o">></span> <span class="o">&</span> <span class="n">handle</span><span class="p">)</span>
|
|
<span class="n">filesystem</span><span class="o">::</span><span class="n">path</span> <span class="n">cwd</span><span class="p">(</span><span class="n">pid_type</span> <span class="n">pid</span><span class="p">,</span> <span class="n">error_code</span> <span class="o">&</span> <span class="n">ec</span><span class="p">);</span>
|
|
<span class="n">filesystem</span><span class="o">::</span><span class="n">path</span> <span class="nf">cwd</span><span class="p">(</span><span class="n">pid_type</span> <span class="n">pid</span><span class="p">);</span>
|
|
|
|
|
|
<span class="c1">// Get the current environment of the process.</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Executor</span><span class="p">></span>
|
|
<span class="n">env_view</span> <span class="nf">cwd</span><span class="p">(</span><span class="n">basic_process_handle</span><span class="o"><</span><span class="n">Executor</span><span class="o">></span> <span class="o">&</span> <span class="n">handle</span><span class="p">,</span> <span class="n">error_code</span> <span class="o">&</span> <span class="n">ec</span><span class="p">);</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Executor</span><span class="p">></span>
|
|
<span class="n">env_view</span> <span class="nf">cwd</span><span class="p">(</span><span class="n">basic_process_handle</span><span class="o"><</span><span class="n">Executor</span><span class="o">></span> <span class="o">&</span> <span class="n">handle</span><span class="p">)</span>
|
|
<span class="n">env_view</span> <span class="n">env</span><span class="p">(</span><span class="n">pid_type</span> <span class="n">pid</span><span class="p">,</span> <span class="n">error_code</span> <span class="o">&</span> <span class="n">ec</span><span class="p">);</span>
|
|
<span class="n">env_view</span> <span class="nf">env</span><span class="p">(</span><span class="n">pid_type</span> <span class="n">pid</span><span class="p">);</span>
|
|
|
|
|
|
<span class="c1">// Get the executable of the process.</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Executor</span><span class="p">></span>
|
|
<span class="n">filesystem</span><span class="o">::</span><span class="n">path</span> <span class="nf">exe</span><span class="p">(</span><span class="n">basic_process_handle</span><span class="o"><</span><span class="n">Executor</span><span class="o">></span> <span class="o">&</span> <span class="n">handle</span><span class="p">,</span> <span class="n">error_code</span> <span class="o">&</span> <span class="n">ec</span><span class="p">);</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Executor</span><span class="p">></span>
|
|
<span class="n">filesystem</span><span class="o">::</span><span class="n">path</span> <span class="nf">exe</span><span class="p">(</span><span class="n">basic_process_handle</span><span class="o"><</span><span class="n">Executor</span><span class="o">></span> <span class="o">&</span> <span class="n">handle</span><span class="p">)</span>
|
|
<span class="n">filesystem</span><span class="o">::</span><span class="n">path</span> <span class="n">exe</span><span class="p">(</span><span class="n">pid_type</span> <span class="n">pid</span><span class="p">,</span> <span class="n">error_code</span> <span class="o">&</span> <span class="n">ec</span><span class="p">);</span>
|
|
<span class="n">filesystem</span><span class="o">::</span><span class="n">path</span> <span class="nf">exe</span><span class="p">(</span><span class="n">pid_type</span> <span class="n">pid</span><span class="p">);</span></code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="admonitionblock warning">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-warning" title="Warning"></i>
|
|
</td>
|
|
<td class="content">
|
|
The function may fail with "operation_not_supported" on some niche platforms.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="admonitionblock note">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-note" title="Note"></i>
|
|
</td>
|
|
<td class="content">
|
|
On windows overloads taking a <code>HANDLE</code> are also available.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="pid_hpp"><code>pid.hpp</code></h3>
|
|
<div id="pid" class="listingblock">
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"><span class="c1">//An integral type representing a process id.</span>
|
|
<span class="k">typedef</span> <span class="n">implementation_defined</span> <span class="n">pid_type</span><span class="p">;</span>
|
|
|
|
<span class="c1">// Get the process id of the current process.</span>
|
|
<span class="n">pid_type</span> <span class="nf">current_pid</span><span class="p">();</span>
|
|
|
|
<span class="c1">// List all available pids.</span>
|
|
<span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">pid_type</span><span class="o">></span> <span class="n">all_pids</span><span class="p">(</span><span class="n">boost</span><span class="o">::</span><span class="n">system</span><span class="o">::</span><span class="n">error_code</span> <span class="o">&</span> <span class="n">ec</span><span class="p">);</span>
|
|
<span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">pid_type</span><span class="o">></span> <span class="n">all_pids</span><span class="p">();</span>
|
|
|
|
<span class="c1">// return parent pid of pid.</span>
|
|
<span class="n">pid_type</span> <span class="nf">parent_pid</span><span class="p">(</span><span class="n">pid_type</span> <span class="n">pid</span><span class="p">,</span> <span class="n">boost</span><span class="o">::</span><span class="n">system</span><span class="o">::</span><span class="n">error_code</span> <span class="o">&</span> <span class="n">ec</span><span class="p">);</span>
|
|
<span class="n">pid_type</span> <span class="nf">parent_pid</span><span class="p">(</span><span class="n">pid_type</span> <span class="n">pid</span><span class="p">);</span>
|
|
|
|
<span class="c1">// return child pids of pid.</span>
|
|
<span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">pid_type</span><span class="o">></span> <span class="n">child_pids</span><span class="p">(</span><span class="n">pid_type</span> <span class="n">pid</span><span class="p">,</span> <span class="n">boost</span><span class="o">::</span><span class="n">system</span><span class="o">::</span><span class="n">error_code</span> <span class="o">&</span> <span class="n">ec</span><span class="p">);</span>
|
|
<span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">pid_type</span><span class="o">></span> <span class="n">child_pids</span><span class="p">(</span><span class="n">pid_type</span> <span class="n">pid</span><span class="p">);</span></code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="popen_hpp"><code>popen.hpp</code></h3>
|
|
<div id="popen" class="paragraph">
|
|
<p><code>popen</code> is a class that launches a process and connect stdin & stdout to pipes.</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"><span class="n">popen</span> <span class="nf">proc</span><span class="p">(</span><span class="n">executor</span><span class="p">,</span> <span class="n">find_executable</span><span class="p">(</span><span class="s">"addr2line"</span><span class="p">),</span> <span class="p">{</span><span class="n">argv</span><span class="p">[</span><span class="mi">0</span><span class="p">]});</span>
|
|
<span class="n">asio</span><span class="o">::</span><span class="n">write</span><span class="p">(</span><span class="n">proc</span><span class="p">,</span> <span class="n">asio</span><span class="o">::</span><span class="n">buffer</span><span class="p">(</span><span class="s">"main</span><span class="se">\n</span><span class="s">"</span><span class="p">));</span>
|
|
<span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">line</span><span class="p">;</span>
|
|
<span class="n">asio</span><span class="o">::</span><span class="n">read_until</span><span class="p">(</span><span class="n">proc</span><span class="p">,</span> <span class="n">asio</span><span class="o">::</span><span class="n">dynamic_buffer</span><span class="p">(</span><span class="n">line</span><span class="p">),</span> <span class="sc">'\n'</span><span class="p">);</span></code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"><span class="c1">// A subprocess with automatically assigned pipes.</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Executor</span> <span class="o">=</span> <span class="n">net</span><span class="o">::</span><span class="n">any_io_executor</span><span class="p">></span>
|
|
<span class="k">struct</span> <span class="nc">basic_popen</span> <span class="o">:</span> <span class="n">basic_process</span><span class="o"><</span><span class="n">Executor</span><span class="o">></span>
|
|
<span class="p">{</span>
|
|
<span class="c1">// The executor of the process</span>
|
|
<span class="k">using</span> <span class="n">executor_type</span> <span class="o">=</span> <span class="n">Executor</span><span class="p">;</span>
|
|
|
|
<span class="c1">// Rebinds the popen type to another executor.</span>
|
|
<span class="k">template</span> <span class="o"><</span><span class="k">typename</span> <span class="nc">Executor1</span><span class="p">></span>
|
|
<span class="k">struct</span> <span class="nc">rebind_executor</span>
|
|
<span class="p">{</span>
|
|
<span class="c1">// The pipe type when rebound to the specified executor.</span>
|
|
<span class="k">typedef</span> <span class="n">basic_popen</span><span class="o"><</span><span class="n">Executor1</span><span class="o">></span> <span class="n">other</span><span class="p">;</span>
|
|
<span class="p">};</span>
|
|
|
|
<span class="c1">// Move construct a popen</span>
|
|
<span class="n">basic_popen</span><span class="p">(</span><span class="n">basic_popen</span> <span class="o">&&</span><span class="p">)</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
|
|
<span class="c1">// Move assign a popen</span>
|
|
<span class="n">basic_popen</span><span class="o">&</span> <span class="k">operator</span><span class="o">=</span><span class="p">(</span><span class="n">basic_popen</span> <span class="o">&&</span><span class="p">)</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
|
|
|
|
<span class="c1">// Move construct a popen and change the executor type.</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Executor1</span><span class="p">></span>
|
|
<span class="n">basic_popen</span><span class="p">(</span><span class="n">basic_popen</span><span class="o"><</span><span class="n">Executor1</span><span class="o">>&&</span> <span class="n">lhs</span><span class="p">)</span>
|
|
<span class="o">:</span> <span class="n">basic_process</span><span class="o"><</span><span class="n">Executor</span><span class="o">></span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">lhs</span><span class="p">)),</span>
|
|
<span class="n">stdin_</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">lhs</span><span class="p">.</span><span class="n">stdin_</span><span class="p">)),</span> <span class="n">stdout_</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">lhs</span><span class="p">.</span><span class="n">stdout_</span><span class="p">))</span>
|
|
<span class="p">{</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="c1">// Create a closed process handle</span>
|
|
<span class="k">explicit</span> <span class="nf">basic_popen</span><span class="p">(</span><span class="n">executor_type</span> <span class="n">exec</span><span class="p">);</span>
|
|
|
|
<span class="c1">// Create a closed process handle</span>
|
|
<span class="k">template</span> <span class="o"><</span><span class="k">typename</span> <span class="nc">ExecutionContext</span><span class="p">></span>
|
|
<span class="k">explicit</span> <span class="nf">basic_popen</span><span class="p">(</span><span class="n">ExecutionContext</span> <span class="o">&</span> <span class="n">context</span><span class="p">);</span>
|
|
|
|
<span class="c1">// Construct a child from a property list and launch it using the default process launcher.</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="o">...</span> <span class="nc">Inits</span><span class="p">></span>
|
|
<span class="k">explicit</span> <span class="nf">basic_popen</span><span class="p">(</span>
|
|
<span class="n">executor_type</span> <span class="n">executor</span><span class="p">,</span>
|
|
<span class="k">const</span> <span class="n">filesystem</span><span class="o">::</span><span class="n">path</span><span class="o">&</span> <span class="n">exe</span><span class="p">,</span>
|
|
<span class="n">std</span><span class="o">::</span><span class="n">initializer_list</span><span class="o"><</span><span class="n">string_view</span><span class="o">></span> <span class="n">args</span><span class="p">,</span>
|
|
<span class="n">Inits</span><span class="o">&&</span><span class="p">...</span> <span class="n">inits</span><span class="p">);</span>
|
|
|
|
<span class="c1">// Construct a child from a property list and launch it using the default process launcher.</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Launcher</span><span class="p">,</span> <span class="k">typename</span> <span class="o">...</span> <span class="nc">Inits</span><span class="p">></span>
|
|
<span class="k">explicit</span> <span class="nf">basic_popen</span><span class="p">(</span>
|
|
<span class="n">Launcher</span> <span class="o">&&</span> <span class="n">launcher</span><span class="p">,</span>
|
|
<span class="n">executor_type</span> <span class="n">executor</span><span class="p">,</span>
|
|
<span class="k">const</span> <span class="n">filesystem</span><span class="o">::</span><span class="n">path</span><span class="o">&</span> <span class="n">exe</span><span class="p">,</span>
|
|
<span class="n">std</span><span class="o">::</span><span class="n">initializer_list</span><span class="o"><</span><span class="n">string_view</span><span class="o">></span> <span class="n">args</span><span class="p">,</span>
|
|
<span class="n">Inits</span><span class="o">&&</span><span class="p">...</span> <span class="n">inits</span><span class="p">);</span>
|
|
|
|
<span class="c1">// Construct a child from a property list and launch it using the default process launcher.</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Args</span><span class="p">,</span> <span class="k">typename</span> <span class="o">...</span> <span class="nc">Inits</span><span class="p">></span>
|
|
<span class="k">explicit</span> <span class="nf">basic_popen</span><span class="p">(</span>
|
|
<span class="n">executor_type</span> <span class="n">executor</span><span class="p">,</span>
|
|
<span class="k">const</span> <span class="n">filesystem</span><span class="o">::</span><span class="n">path</span><span class="o">&</span> <span class="n">exe</span><span class="p">,</span>
|
|
<span class="n">Args</span><span class="o">&&</span> <span class="n">args</span><span class="p">,</span> <span class="n">Inits</span><span class="o">&&</span><span class="p">...</span> <span class="n">inits</span><span class="p">);</span>
|
|
|
|
<span class="c1">// Construct a child from a property list and launch it using the default process launcher.</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Launcher</span><span class="p">,</span> <span class="k">typename</span> <span class="nc">Args</span><span class="p">,</span> <span class="k">typename</span> <span class="o">...</span> <span class="nc">Inits</span><span class="p">></span>
|
|
<span class="k">explicit</span> <span class="nf">basic_popen</span><span class="p">(</span>
|
|
<span class="n">Launcher</span> <span class="o">&&</span> <span class="n">launcher</span><span class="p">,</span>
|
|
<span class="n">executor_type</span> <span class="n">executor</span><span class="p">,</span>
|
|
<span class="k">const</span> <span class="n">filesystem</span><span class="o">::</span><span class="n">path</span><span class="o">&</span> <span class="n">exe</span><span class="p">,</span>
|
|
<span class="n">Args</span><span class="o">&&</span> <span class="n">args</span><span class="p">,</span> <span class="n">Inits</span><span class="o">&&</span><span class="p">...</span> <span class="n">inits</span><span class="p">);</span>
|
|
|
|
<span class="c1">// Construct a child from a property list and launch it using the default process launcher.</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">ExecutionContext</span><span class="p">,</span> <span class="k">typename</span> <span class="o">...</span> <span class="nc">Inits</span><span class="p">></span>
|
|
<span class="k">explicit</span> <span class="nf">basic_popen</span><span class="p">(</span>
|
|
<span class="n">ExecutionContext</span> <span class="o">&</span> <span class="n">context</span><span class="p">,</span>
|
|
<span class="k">const</span> <span class="n">filesystem</span><span class="o">::</span><span class="n">path</span><span class="o">&</span> <span class="n">exe</span><span class="p">,</span>
|
|
<span class="n">std</span><span class="o">::</span><span class="n">initializer_list</span><span class="o"><</span><span class="n">string_view</span><span class="o">></span> <span class="n">args</span><span class="p">,</span>
|
|
<span class="n">Inits</span><span class="o">&&</span><span class="p">...</span> <span class="n">inits</span><span class="p">);</span>
|
|
|
|
<span class="c1">// Construct a child from a property list and launch it using the default process launcher.</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Launcher</span><span class="p">,</span> <span class="k">typename</span> <span class="nc">ExecutionContext</span><span class="p">,</span> <span class="k">typename</span> <span class="o">...</span> <span class="nc">Inits</span><span class="p">></span>
|
|
<span class="k">explicit</span> <span class="nf">basic_popen</span><span class="p">(</span>
|
|
<span class="n">Launcher</span> <span class="o">&&</span> <span class="n">launcher</span><span class="p">,</span>
|
|
<span class="n">ExecutionContext</span> <span class="o">&</span> <span class="n">context</span><span class="p">,</span>
|
|
<span class="k">const</span> <span class="n">filesystem</span><span class="o">::</span><span class="n">path</span><span class="o">&</span> <span class="n">exe</span><span class="p">,</span>
|
|
<span class="n">std</span><span class="o">::</span><span class="n">initializer_list</span><span class="o"><</span><span class="n">string_view</span><span class="o">></span> <span class="n">args</span><span class="p">,</span>
|
|
<span class="n">Inits</span><span class="o">&&</span><span class="p">...</span> <span class="n">inits</span><span class="p">);</span>
|
|
|
|
<span class="c1">// Construct a child from a property list and launch it using the default process launcher.</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">ExecutionContext</span><span class="p">,</span> <span class="k">typename</span> <span class="nc">Args</span><span class="p">,</span> <span class="k">typename</span> <span class="o">...</span> <span class="nc">Inits</span><span class="p">></span>
|
|
<span class="k">explicit</span> <span class="nf">basic_popen</span><span class="p">(</span>
|
|
<span class="n">ExecutionContext</span> <span class="o">&</span> <span class="n">context</span><span class="p">,</span>
|
|
<span class="k">const</span> <span class="n">filesystem</span><span class="o">::</span><span class="n">path</span><span class="o">&</span> <span class="n">exe</span><span class="p">,</span>
|
|
<span class="n">Args</span><span class="o">&&</span> <span class="n">args</span><span class="p">,</span> <span class="n">Inits</span><span class="o">&&</span><span class="p">...</span> <span class="n">inits</span><span class="p">);</span>
|
|
|
|
<span class="c1">// Construct a child from a property list and launch it using the default process launcher.</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Launcher</span><span class="p">,</span> <span class="k">typename</span> <span class="nc">ExecutionContext</span><span class="p">,</span> <span class="k">typename</span> <span class="nc">Args</span><span class="p">,</span> <span class="k">typename</span> <span class="o">...</span> <span class="nc">Inits</span><span class="p">></span>
|
|
<span class="k">explicit</span> <span class="nf">basic_popen</span><span class="p">(</span>
|
|
<span class="n">Launcher</span> <span class="o">&&</span> <span class="n">launcher</span><span class="p">,</span>
|
|
<span class="n">ExecutionContext</span> <span class="o">&</span> <span class="n">context</span><span class="p">,</span>
|
|
<span class="k">const</span> <span class="n">filesystem</span><span class="o">::</span><span class="n">path</span><span class="o">&</span> <span class="n">exe</span><span class="p">,</span>
|
|
<span class="n">Args</span><span class="o">&&</span> <span class="n">args</span><span class="p">,</span> <span class="n">Inits</span><span class="o">&&</span><span class="p">...</span> <span class="n">inits</span><span class="p">);</span>
|
|
|
|
<span class="c1">// The type used for stdin on the parent process side.</span>
|
|
<span class="k">using</span> <span class="n">stdin_type</span> <span class="o">=</span> <span class="n">net</span><span class="o">::</span><span class="n">basic_writable_pipe</span><span class="o"><</span><span class="n">Executor</span><span class="o">></span><span class="p">;</span>
|
|
<span class="c1">// The type used for stdout on the parent process side.</span>
|
|
<span class="k">using</span> <span class="n">stdout_type</span> <span class="o">=</span> <span class="n">net</span><span class="o">::</span><span class="n">basic_readable_pipe</span><span class="o"><</span><span class="n">Executor</span><span class="o">></span><span class="p">;</span>
|
|
|
|
<span class="c1">// Get the stdin pipe.</span>
|
|
|
|
<span class="c1">// Get the stdout pipe.</span>
|
|
|
|
<span class="c1">// Get the stdin pipe.</span>
|
|
<span class="n">stdin_type</span> <span class="o">&</span> <span class="n">get_stdin</span><span class="p">();</span>
|
|
<span class="k">const</span> <span class="n">stdin_type</span> <span class="o">&</span> <span class="n">get_stdin</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="c1">// Get the stdout pipe.</span>
|
|
<span class="n">stdout_type</span> <span class="o">&</span> <span class="n">get_stdout</span><span class="p">();</span>
|
|
<span class="k">const</span> <span class="n">stdout_type</span> <span class="o">&</span> <span class="n">get_stdout</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
|
|
<span class="c1">// Write some data to the stdin pipe.</span>
|
|
<span class="k">template</span> <span class="o"><</span><span class="k">typename</span> <span class="nc">ConstBufferSequence</span><span class="p">></span>
|
|
<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="nf">write_some</span><span class="p">(</span><span class="k">const</span> <span class="n">ConstBufferSequence</span><span class="o">&</span> <span class="n">buffers</span><span class="p">);</span>
|
|
<span class="k">template</span> <span class="o"><</span><span class="k">typename</span> <span class="nc">ConstBufferSequence</span><span class="p">></span>
|
|
<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="nf">write_some</span><span class="p">(</span><span class="k">const</span> <span class="n">ConstBufferSequence</span><span class="o">&</span> <span class="n">buffers</span><span class="p">,</span>
|
|
<span class="n">boost</span><span class="o">::</span><span class="n">system</span><span class="o">::</span><span class="n">error_code</span><span class="o">&</span> <span class="n">ec</span><span class="p">);</span>
|
|
|
|
<span class="c1">// Start an asynchronous write.</span>
|
|
<span class="k">template</span> <span class="o"><</span><span class="k">typename</span> <span class="nc">ConstBufferSequence</span><span class="p">,</span>
|
|
<span class="n">BOOST_ASIO_COMPLETION_TOKEN_FOR</span><span class="p">(</span><span class="kt">void</span> <span class="p">(</span><span class="n">boost</span><span class="o">::</span><span class="n">system</span><span class="o">::</span><span class="n">error_code</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span><span class="p">))</span>
|
|
<span class="n">WriteToken</span> <span class="o">=</span> <span class="n">net</span><span class="o">::</span><span class="n">default_completion_token_t</span><span class="o"><</span><span class="n">executor_type</span><span class="p">></span><span class="o">></span>
|
|
<span class="k">auto</span> <span class="nf">async_write_some</span><span class="p">(</span><span class="k">const</span> <span class="n">ConstBufferSequence</span><span class="o">&</span> <span class="n">buffers</span><span class="p">,</span>
|
|
<span class="n">WriteToken</span> <span class="o">&&</span> <span class="n">token</span> <span class="o">=</span> <span class="n">net</span><span class="o">::</span><span class="n">default_completion_token_t</span><span class="o"><</span><span class="n">executor_type</span><span class="o">></span><span class="p">());</span>
|
|
|
|
<span class="c1">// Read some data from the stdout pipe.</span>
|
|
<span class="k">template</span> <span class="o"><</span><span class="k">typename</span> <span class="nc">MutableBufferSequence</span><span class="p">></span>
|
|
<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="nf">read_some</span><span class="p">(</span><span class="k">const</span> <span class="n">MutableBufferSequence</span><span class="o">&</span> <span class="n">buffers</span><span class="p">);</span>
|
|
<span class="k">template</span> <span class="o"><</span><span class="k">typename</span> <span class="nc">MutableBufferSequence</span><span class="p">></span>
|
|
<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="nf">read_some</span><span class="p">(</span><span class="k">const</span> <span class="n">MutableBufferSequence</span><span class="o">&</span> <span class="n">buffers</span><span class="p">,</span>
|
|
<span class="n">boost</span><span class="o">::</span><span class="n">system</span><span class="o">::</span><span class="n">error_code</span><span class="o">&</span> <span class="n">ec</span><span class="p">)</span>
|
|
|
|
<span class="c1">// Start an asynchronous read. template <typename MutableBufferSequence,</span>
|
|
<span class="n">BOOST_PROCESS_V2_COMPLETION_TOKEN_FOR</span><span class="p">(</span><span class="kt">void</span> <span class="p">(</span><span class="n">boost</span><span class="o">::</span><span class="n">system</span><span class="o">::</span><span class="n">error_code</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span><span class="p">))</span>
|
|
<span class="n">ReadToken</span> <span class="o">=</span> <span class="n">net</span><span class="o">::</span><span class="n">default_completion_token_t</span><span class="o"><</span><span class="n">executor_type</span><span class="o">>></span>
|
|
<span class="k">auto</span> <span class="n">async_read_some</span><span class="p">(</span><span class="k">const</span> <span class="n">MutableBufferSequence</span><span class="o">&</span> <span class="n">buffers</span><span class="p">,</span>
|
|
<span class="n">BOOST_ASIO_MOVE_ARG</span><span class="p">(</span><span class="n">ReadToken</span><span class="p">)</span> <span class="n">token</span>
|
|
<span class="o">=</span> <span class="n">net</span><span class="o">::</span><span class="n">default_completion_token_t</span><span class="o"><</span><span class="n">executor_type</span><span class="o">></span><span class="p">());</span>
|
|
<span class="p">};</span>
|
|
|
|
<span class="c1">// A popen object with the default executor.</span>
|
|
<span class="k">using</span> <span class="n">popen</span> <span class="o">=</span> <span class="n">basic_popen</span><span class="o"><></span><span class="p">;</span></code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="process_hpp"><code>process.hpp</code></h3>
|
|
<div id="process" class="listingblock">
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"><span class="c1">// A class managing a subprocess</span>
|
|
<span class="cm">/* A `basic_process` object manages a subprocess; it tracks the status and exit-code,
|
|
* and will terminate the process on destruction if `detach` was not called.
|
|
*/</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Executor</span> <span class="o">=</span> <span class="n">net</span><span class="o">::</span><span class="n">any_io_executor</span><span class="p">></span>
|
|
<span class="k">struct</span> <span class="nc">basic_process</span>
|
|
<span class="p">{</span>
|
|
<span class="c1">// The executor of the process</span>
|
|
<span class="k">using</span> <span class="n">executor_type</span> <span class="o">=</span> <span class="n">Executor</span><span class="p">;</span>
|
|
<span class="c1">// Get the executor of the process</span>
|
|
<span class="n">executor_type</span> <span class="n">get_executor</span><span class="p">()</span> <span class="p">{</span><span class="k">return</span> <span class="n">process_handle_</span><span class="p">.</span><span class="n">get_executor</span><span class="p">();}</span>
|
|
|
|
<span class="c1">// The non-closing handle type</span>
|
|
<span class="k">using</span> <span class="n">handle_type</span> <span class="o">=</span> <span class="n">basic_process_handle</span><span class="o"><</span><span class="n">executor_type</span><span class="o">></span><span class="p">;</span>
|
|
|
|
<span class="c1">// Get the underlying non-closing handle</span>
|
|
<span class="n">handle_type</span> <span class="o">&</span> <span class="n">handle</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="n">process_handle_</span><span class="p">;</span> <span class="p">}</span>
|
|
|
|
<span class="c1">// Get the underlying non-closing handle</span>
|
|
<span class="k">const</span> <span class="n">handle_type</span> <span class="o">&</span> <span class="n">handle</span><span class="p">()</span> <span class="k">const</span> <span class="p">{</span> <span class="k">return</span> <span class="n">process_handle_</span><span class="p">;</span> <span class="p">}</span>
|
|
|
|
<span class="c1">// Provides access to underlying operating system facilities</span>
|
|
<span class="k">using</span> <span class="n">native_handle_type</span> <span class="o">=</span> <span class="k">typename</span> <span class="n">handle_type</span><span class="o">::</span><span class="n">native_handle_type</span><span class="p">;</span>
|
|
|
|
<span class="c1">// Rebinds the process_handle to another executor.</span>
|
|
<span class="k">template</span> <span class="o"><</span><span class="k">typename</span> <span class="nc">Executor1</span><span class="p">></span>
|
|
<span class="k">struct</span> <span class="nc">rebind_executor</span>
|
|
<span class="p">{</span>
|
|
<span class="c1">// The socket type when rebound to the specified executor.</span>
|
|
<span class="k">typedef</span> <span class="n">basic_process</span><span class="o"><</span><span class="n">Executor1</span><span class="o">></span> <span class="n">other</span><span class="p">;</span>
|
|
<span class="p">};</span>
|
|
|
|
<span class="cm">/** An empty process is similar to a default constructed thread. It holds an empty
|
|
handle and is a place holder for a process that is to be launched later. */</span>
|
|
<span class="n">basic_process</span><span class="p">()</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
|
|
|
|
<span class="n">basic_process</span><span class="p">(</span><span class="k">const</span> <span class="n">basic_process</span><span class="o">&</span><span class="p">)</span> <span class="o">=</span> <span class="k">delete</span><span class="p">;</span>
|
|
<span class="n">basic_process</span><span class="o">&</span> <span class="k">operator</span><span class="o">=</span><span class="p">(</span><span class="k">const</span> <span class="n">basic_process</span><span class="o">&</span><span class="p">)</span> <span class="o">=</span> <span class="k">delete</span><span class="p">;</span>
|
|
|
|
<span class="c1">// Move construct the process. It will be detached from `lhs`.</span>
|
|
<span class="n">basic_process</span><span class="p">(</span><span class="n">basic_process</span><span class="o">&&</span> <span class="n">lhs</span><span class="p">)</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
|
|
|
|
<span class="c1">// Move assign a process. It will be detached from `lhs`.</span>
|
|
<span class="n">basic_process</span><span class="o">&</span> <span class="k">operator</span><span class="o">=</span><span class="p">(</span><span class="n">basic_process</span><span class="o">&&</span> <span class="n">lhs</span><span class="p">)</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
|
|
|
|
<span class="c1">// Move construct and rebind the executor.</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Executor1</span><span class="p">></span>
|
|
<span class="n">basic_process</span><span class="p">(</span><span class="n">basic_process</span><span class="o"><</span><span class="n">Executor1</span><span class="o">>&&</span> <span class="n">lhs</span><span class="p">);</span>
|
|
|
|
<span class="c1">// Construct a child from a property list and launch it using the default launcher..</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="o">...</span> <span class="nc">Inits</span><span class="p">></span>
|
|
<span class="k">explicit</span> <span class="nf">basic_process</span><span class="p">(</span>
|
|
<span class="n">executor_type</span> <span class="n">executor</span><span class="p">,</span>
|
|
<span class="k">const</span> <span class="n">filesystem</span><span class="o">::</span><span class="n">path</span><span class="o">&</span> <span class="n">exe</span><span class="p">,</span>
|
|
<span class="n">std</span><span class="o">::</span><span class="n">initializer_list</span><span class="o"><</span><span class="n">string_view</span><span class="o">></span> <span class="n">args</span><span class="p">,</span>
|
|
<span class="n">Inits</span><span class="o">&&</span><span class="p">...</span> <span class="n">inits</span><span class="p">);</span>
|
|
|
|
<span class="c1">// Construct a child from a property list and launch it using the default launcher..</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Args</span><span class="p">,</span> <span class="k">typename</span> <span class="o">...</span> <span class="nc">Inits</span><span class="p">></span>
|
|
<span class="k">explicit</span> <span class="nf">basic_process</span><span class="p">(</span>
|
|
<span class="n">executor_type</span> <span class="n">executor</span><span class="p">,</span>
|
|
<span class="k">const</span> <span class="n">filesystem</span><span class="o">::</span><span class="n">path</span><span class="o">&</span> <span class="n">exe</span><span class="p">,</span>
|
|
<span class="n">Args</span><span class="o">&&</span> <span class="n">args</span><span class="p">,</span> <span class="n">Inits</span><span class="o">&&</span><span class="p">...</span> <span class="n">inits</span><span class="p">);</span>
|
|
|
|
<span class="c1">// Construct a child from a property list and launch it using the default launcher..</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">ExecutionContext</span><span class="p">,</span> <span class="k">typename</span> <span class="o">...</span> <span class="nc">Inits</span><span class="p">></span>
|
|
<span class="k">explicit</span> <span class="nf">basic_process</span><span class="p">(</span>
|
|
<span class="n">ExecutionContext</span> <span class="o">&</span> <span class="n">context</span><span class="p">,</span>
|
|
<span class="k">const</span> <span class="n">filesystem</span><span class="o">::</span><span class="n">path</span><span class="o">&</span> <span class="n">exe</span><span class="p">,</span>
|
|
<span class="n">std</span><span class="o">::</span><span class="n">initializer_list</span><span class="o"><</span><span class="n">string_view</span><span class="o">></span> <span class="n">args</span><span class="p">,</span>
|
|
<span class="n">Inits</span><span class="o">&&</span><span class="p">...</span> <span class="n">inits</span><span class="p">);</span>
|
|
<span class="c1">// Construct a child from a property list and launch it using the default launcher.</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">ExecutionContext</span><span class="p">,</span> <span class="k">typename</span> <span class="nc">Args</span><span class="p">,</span> <span class="k">typename</span> <span class="o">...</span> <span class="nc">Inits</span><span class="p">></span>
|
|
<span class="k">explicit</span> <span class="nf">basic_process</span><span class="p">(</span>
|
|
<span class="n">ExecutionContext</span> <span class="o">&</span> <span class="n">context</span><span class="p">,</span>
|
|
<span class="k">const</span> <span class="n">filesystem</span><span class="o">::</span><span class="n">path</span><span class="o">&</span> <span class="n">exe</span><span class="p">,</span>
|
|
<span class="n">Args</span><span class="o">&&</span> <span class="n">args</span><span class="p">,</span> <span class="n">Inits</span><span class="o">&&</span><span class="p">...</span> <span class="n">inits</span><span class="p">);</span>
|
|
|
|
<span class="c1">// Attach to an existing process</span>
|
|
<span class="k">explicit</span> <span class="nf">basic_process</span><span class="p">(</span><span class="n">executor_type</span> <span class="n">exec</span><span class="p">,</span> <span class="n">pid_type</span> <span class="n">pid</span><span class="p">);</span>
|
|
|
|
<span class="c1">// Attach to an existing process and the internal handle</span>
|
|
<span class="k">explicit</span> <span class="nf">basic_process</span><span class="p">(</span><span class="n">executor_type</span> <span class="n">exec</span><span class="p">,</span> <span class="n">pid_type</span> <span class="n">pid</span><span class="p">,</span> <span class="n">native_handle_type</span> <span class="n">native_handle</span><span class="p">);</span>
|
|
|
|
<span class="c1">// Create an invalid handle</span>
|
|
<span class="k">explicit</span> <span class="nf">basic_process</span><span class="p">(</span><span class="n">executor_type</span> <span class="n">exec</span><span class="p">);</span>
|
|
|
|
<span class="c1">// Attach to an existing process</span>
|
|
<span class="k">template</span> <span class="o"><</span><span class="k">typename</span> <span class="nc">ExecutionContext</span><span class="p">></span>
|
|
<span class="k">explicit</span> <span class="nf">basic_process</span><span class="p">(</span><span class="n">ExecutionContext</span> <span class="o">&</span> <span class="n">context</span><span class="p">,</span> <span class="n">pid_type</span> <span class="n">pid</span><span class="p">);</span>
|
|
|
|
<span class="c1">// Attach to an existing process and the internal handle</span>
|
|
<span class="k">template</span> <span class="o"><</span><span class="k">typename</span> <span class="nc">ExecutionContext</span><span class="p">></span>
|
|
<span class="k">explicit</span> <span class="nf">basic_process</span><span class="p">(</span><span class="n">ExecutionContext</span> <span class="o">&</span> <span class="n">context</span><span class="p">,</span> <span class="n">pid_type</span> <span class="n">pid</span><span class="p">,</span> <span class="n">native_handle_type</span> <span class="n">native_handle</span><span class="p">);</span>
|
|
|
|
<span class="c1">// Create an invalid handle</span>
|
|
<span class="k">template</span> <span class="o"><</span><span class="k">typename</span> <span class="nc">ExecutionContext</span><span class="p">></span>
|
|
<span class="k">explicit</span> <span class="nf">basic_process</span><span class="p">(</span><span class="n">ExecutionContext</span> <span class="o">&</span> <span class="n">context</span><span class="p">);</span>
|
|
|
|
|
|
|
|
<span class="c1">// Destruct the handle and terminate the process if it wasn't detached.</span>
|
|
<span class="o">~</span><span class="n">basic_process</span><span class="p">();</span>
|
|
|
|
<span class="c1">// Sends the process a signal to ask for an interrupt, which the process may interpret as a shutdown.</span>
|
|
<span class="cm">/** Maybe be ignored by the subprocess. */</span>
|
|
<span class="kt">void</span> <span class="nf">interrupt</span><span class="p">(</span><span class="n">error_code</span> <span class="o">&</span> <span class="n">ec</span><span class="p">);</span>
|
|
<span class="kt">void</span> <span class="nf">interrupt</span><span class="p">();</span>
|
|
|
|
<span class="c1">// Throwing @overload void interrupt()</span>
|
|
|
|
|
|
<span class="c1">// Sends the process a signal to ask for a graceful shutdown. Maybe be ignored by the subprocess.</span>
|
|
<span class="kt">void</span> <span class="nf">request_exit</span><span class="p">(</span><span class="n">error_code</span> <span class="o">&</span> <span class="n">ec</span><span class="p">);</span>
|
|
<span class="kt">void</span> <span class="nf">request_exit</span><span class="p">();</span>
|
|
|
|
<span class="c1">// Send the process a signal requesting it to stop. This may rely on undocumented functions.</span>
|
|
<span class="kt">void</span> <span class="nf">suspend</span><span class="p">(</span><span class="n">error_code</span> <span class="o">&</span><span class="n">ec</span><span class="p">);</span>
|
|
<span class="kt">void</span> <span class="nf">suspend</span><span class="p">();</span>
|
|
|
|
|
|
<span class="c1">// Send the process a signal requesting it to resume. This may rely on undocumented functions.</span>
|
|
<span class="kt">void</span> <span class="nf">resume</span><span class="p">(</span><span class="n">error_code</span> <span class="o">&</span><span class="n">ec</span><span class="p">);</span>
|
|
<span class="kt">void</span> <span class="nf">resume</span><span class="p">();</span>
|
|
|
|
<span class="c1">// Unconditionally terminates the process and stores the exit code in exit_status.</span>
|
|
<span class="kt">void</span> <span class="nf">terminate</span><span class="p">(</span><span class="n">error_code</span> <span class="o">&</span> <span class="n">ec</span><span class="p">);</span>
|
|
<span class="kt">void</span> <span class="nf">terminate</span><span class="p">();</span>
|
|
|
|
<span class="c1">// Waits for the process to exit, store the exit code internally and return it.</span>
|
|
<span class="kt">int</span> <span class="nf">wait</span><span class="p">(</span><span class="n">error_code</span> <span class="o">&</span> <span class="n">ec</span><span class="p">);</span>
|
|
<span class="kt">int</span> <span class="nf">wait</span><span class="p">();</span>
|
|
|
|
<span class="c1">// Detach the process.</span>
|
|
<span class="n">handle_type</span> <span class="nf">detach</span><span class="p">();</span>
|
|
<span class="c1">// Get the native</span>
|
|
<span class="n">native_handle_type</span> <span class="nf">native_handle</span><span class="p">()</span> <span class="p">{</span><span class="k">return</span> <span class="n">process_handle_</span><span class="p">.</span><span class="n">native_handle</span><span class="p">();</span> <span class="p">}</span>
|
|
|
|
<span class="c1">// Return the evaluated exit_code.</span>
|
|
<span class="kt">int</span> <span class="n">exit_code</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
|
|
<span class="c1">// Get the id of the process;</span>
|
|
<span class="n">pid_type</span> <span class="n">id</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
|
|
<span class="c1">// The native handle of the process.</span>
|
|
<span class="cm">/** This might be undefined on posix systems that only support signals */</span>
|
|
<span class="n">native_exit_code_type</span> <span class="n">native_exit_code</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
|
|
<span class="c1">// Checks if the current process is running.</span>
|
|
<span class="cm">/* If it has already completed the exit code will be stored internally
|
|
* and can be obtained by calling `exit_code.
|
|
*/</span>
|
|
<span class="kt">bool</span> <span class="nf">running</span><span class="p">();</span>
|
|
<span class="kt">bool</span> <span class="n">running</span><span class="p">(</span><span class="n">error_code</span> <span class="o">&</span> <span class="n">ec</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</span>
|
|
|
|
<span class="c1">// Check if the process is referring to an existing process.</span>
|
|
<span class="cm">/** Note that this might be a process that already exited.*/</span>
|
|
<span class="kt">bool</span> <span class="n">is_open</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
|
|
<span class="c1">// Asynchronously wait for the process to exit and deliver the native exit-code in the completion handler.</span>
|
|
<span class="k">template</span> <span class="o"><</span><span class="n">BOOST_PROCESS_V2_COMPLETION_TOKEN_FOR</span><span class="p">(</span><span class="kt">void</span> <span class="p">(</span><span class="n">error_code</span><span class="p">,</span> <span class="kt">int</span><span class="p">))</span>
|
|
<span class="n">WaitHandler</span> <span class="o">=</span> <span class="n">net</span><span class="o">::</span><span class="n">default_completion_token_t</span><span class="o"><</span><span class="n">executor_type</span><span class="p">></span><span class="o">></span>
|
|
<span class="k">auto</span> <span class="nf">async_wait</span><span class="p">(</span><span class="n">WaitHandler</span> <span class="o">&&</span> <span class="n">handler</span> <span class="o">=</span> <span class="n">net</span><span class="o">::</span><span class="n">default_completion_token_t</span><span class="o"><</span><span class="n">executor_type</span><span class="o">></span><span class="p">());</span>
|
|
<span class="p">};</span>
|
|
|
|
<span class="c1">// Process with the default executor.</span>
|
|
<span class="k">typedef</span> <span class="n">basic_process</span><span class="o"><></span> <span class="n">process</span><span class="p">;</span></code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="process_handle_hpp"><code>process_handle.hpp</code></h3>
|
|
<div id="process_handle" class="paragraph">
|
|
<p>A process handle is an unmanaged version of a process.
|
|
This means it does not terminate the process on destruction and
|
|
will not keep track of the exit-code.</p>
|
|
</div>
|
|
<div class="admonitionblock note">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-note" title="Note"></i>
|
|
</td>
|
|
<td class="content">
|
|
that the exit code might be discovered early, during a call to <code>running</code>.
|
|
Thus it can only be discovered that process has exited already.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"><span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Executor</span> <span class="o">=</span> <span class="n">net</span><span class="o">::</span><span class="n">any_io_executor</span><span class="p">></span>
|
|
<span class="k">struct</span> <span class="nc">basic_process_handle</span>
|
|
<span class="p">{</span>
|
|
<span class="c1">// The native handle of the process.</span>
|
|
<span class="cm">/* This might be undefined on posix systems that only support signals */</span>
|
|
<span class="k">using</span> <span class="n">native_handle_type</span> <span class="o">=</span> <span class="n">implementation_defined</span><span class="p">;</span>
|
|
|
|
<span class="c1">// The executor_type of the process_handle</span>
|
|
<span class="k">using</span> <span class="n">executor_type</span> <span class="o">=</span> <span class="n">Executor</span><span class="p">;</span>
|
|
|
|
<span class="c1">// Getter for the executor</span>
|
|
<span class="n">executor_type</span> <span class="n">get_executor</span><span class="p">();</span>
|
|
|
|
<span class="c1">// Rebinds the process_handle to another executor.</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Executor1</span><span class="p">></span>
|
|
<span class="k">struct</span> <span class="nc">rebind_executor</span>
|
|
<span class="p">{</span>
|
|
<span class="c1">// The socket type when rebound to the specified executor.</span>
|
|
<span class="k">typedef</span> <span class="n">basic_process_handle</span><span class="o"><</span><span class="n">Executor1</span><span class="o">></span> <span class="n">other</span><span class="p">;</span>
|
|
<span class="p">};</span>
|
|
|
|
|
|
<span class="c1">// Construct a basic_process_handle from an execution_context.</span>
|
|
<span class="cm">/*
|
|
* @tparam ExecutionContext The context must fulfill the asio::execution_context requirements
|
|
*/</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">ExecutionContext</span><span class="p">></span>
|
|
<span class="n">basic_process_handle</span><span class="p">(</span><span class="n">ExecutionContext</span> <span class="o">&</span><span class="n">context</span><span class="p">);</span>
|
|
|
|
<span class="c1">// Construct an empty process_handle from an executor.</span>
|
|
<span class="n">basic_process_handle</span><span class="p">(</span><span class="n">executor_type</span> <span class="n">executor</span><span class="p">);</span>
|
|
|
|
<span class="c1">// Construct an empty process_handle from an executor and bind it to a pid.</span>
|
|
<span class="cm">/* On NON-linux posix systems this call is not able to obtain a file-descriptor and will thus
|
|
* rely on signals.
|
|
*/</span>
|
|
<span class="n">basic_process_handle</span><span class="p">(</span><span class="n">executor_type</span> <span class="n">executor</span><span class="p">,</span> <span class="n">pid_type</span> <span class="n">pid</span><span class="p">);</span>
|
|
|
|
<span class="c1">// Construct an empty process_handle from an executor and bind it to a pid and the native-handle</span>
|
|
<span class="cm">/* On some non-linux posix systems this overload is not present.
|
|
*/</span>
|
|
<span class="n">basic_process_handle</span><span class="p">(</span><span class="n">executor_type</span> <span class="n">executor</span><span class="p">,</span> <span class="n">pid_type</span> <span class="n">pid</span><span class="p">,</span> <span class="n">native_handle_type</span> <span class="n">process_handle</span><span class="p">);</span>
|
|
|
|
<span class="c1">// Move construct and rebind the executor.</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Executor1</span><span class="p">></span>
|
|
<span class="n">basic_process_handle</span><span class="p">(</span><span class="n">basic_process_handle</span><span class="o"><</span><span class="n">Executor1</span><span class="o">></span> <span class="o">&&</span><span class="n">handle</span><span class="p">);</span>
|
|
|
|
<span class="c1">// Get the id of the process</span>
|
|
<span class="n">pid_type</span> <span class="n">id</span><span class="p">()</span> <span class="k">const</span>
|
|
<span class="p">{</span> <span class="k">return</span> <span class="n">pid_</span><span class="p">;</span> <span class="p">}</span>
|
|
|
|
<span class="c1">// Terminate the process if it's still running and ignore the result</span>
|
|
<span class="kt">void</span> <span class="nf">terminate_if_running</span><span class="p">(</span><span class="n">error_code</span> <span class="o">&</span><span class="p">);</span>
|
|
|
|
<span class="c1">// Throwing @overload void terminate_if_running(error_code & ec;</span>
|
|
<span class="kt">void</span> <span class="nf">terminate_if_running</span><span class="p">();</span>
|
|
<span class="c1">// wait for the process to exit and store the exit code in exit_status.</span>
|
|
<span class="kt">void</span> <span class="nf">wait</span><span class="p">(</span><span class="n">native_exit_code_type</span> <span class="o">&</span><span class="n">exit_status</span><span class="p">,</span> <span class="n">error_code</span> <span class="o">&</span><span class="n">ec</span><span class="p">);</span>
|
|
<span class="c1">// Throwing @overload wait(native_exit_code_type &exit_code, error_code & ec)</span>
|
|
<span class="kt">void</span> <span class="nf">wait</span><span class="p">(</span><span class="n">native_exit_code_type</span> <span class="o">&</span><span class="n">exit_status</span><span class="p">);</span>
|
|
|
|
<span class="c1">// Sends the process a signal to ask for an interrupt, which the process may interpret as a shutdown.</span>
|
|
<span class="cm">/* Maybe be ignored by the subprocess. */</span>
|
|
<span class="kt">void</span> <span class="nf">interrupt</span><span class="p">(</span><span class="n">error_code</span> <span class="o">&</span><span class="n">ec</span><span class="p">);</span>
|
|
|
|
<span class="c1">// Throwing @overload void interrupt()</span>
|
|
<span class="kt">void</span> <span class="nf">interrupt</span><span class="p">();</span>
|
|
|
|
<span class="c1">// Sends the process a signal to ask for a graceful shutdown. Maybe be ignored by the subprocess.</span>
|
|
<span class="kt">void</span> <span class="nf">request_exit</span><span class="p">(</span><span class="n">error_code</span> <span class="o">&</span><span class="n">ec</span><span class="p">);</span>
|
|
|
|
<span class="c1">// Throwing @overload void request_exit(error_code & ec)</span>
|
|
<span class="kt">void</span> <span class="nf">request_exit</span><span class="p">()</span>
|
|
|
|
<span class="c1">// Unconditionally terminates the process and stores the exit code in exit_status.</span>
|
|
<span class="kt">void</span> <span class="n">terminate</span><span class="p">(</span><span class="n">native_exit_code_type</span> <span class="o">&</span><span class="n">exit_status</span><span class="p">,</span> <span class="n">error_code</span> <span class="o">&</span><span class="n">ec</span><span class="p">);</span>\
|
|
<span class="c1">// Throwing @overload void terminate(native_exit_code_type &exit_code, error_code & ec)</span>
|
|
<span class="kt">void</span> <span class="nf">terminate</span><span class="p">(</span><span class="n">native_exit_code_type</span> <span class="o">&</span><span class="n">exit_status</span><span class="p">);</span><span class="o">/</span>
|
|
|
|
<span class="c1">// Checks if the current process is running.</span>
|
|
<span class="cm">/*If it has already completed, it assigns the exit code to `exit_code`.
|
|
*/</span>
|
|
<span class="kt">bool</span> <span class="nf">running</span><span class="p">(</span><span class="n">native_exit_code_type</span> <span class="o">&</span><span class="n">exit_code</span><span class="p">,</span> <span class="n">error_code</span> <span class="o">&</span><span class="n">ec</span><span class="p">);</span>
|
|
<span class="c1">// Throwing @overload bool running(native_exit_code_type &exit_code, error_code & ec)</span>
|
|
<span class="kt">bool</span> <span class="nf">running</span><span class="p">(</span><span class="n">native_exit_code_type</span> <span class="o">&</span><span class="n">exit_code</span><span class="p">);</span>
|
|
|
|
<span class="c1">// Check if the process handle is referring to an existing process.</span>
|
|
<span class="kt">bool</span> <span class="n">is_open</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
|
|
<span class="c1">// Asynchronously wait for the process to exit and assign the native exit-code to the reference.</span>
|
|
<span class="c1">// The exit_status can indicate that a process has already be waited for, e.g. when terminate is called.</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="n">BOOST_PROCESS_V2_COMPLETION_TOKEN_FOR</span><span class="p">(</span><span class="kt">void</span><span class="p">(</span><span class="n">error_code</span><span class="p">))</span>
|
|
<span class="n">WaitHandler</span> <span class="o">=</span> <span class="n">net</span><span class="o">::</span><span class="n">default_completion_token_t</span><span class="o"><</span><span class="n">executor_type</span><span class="p">></span><span class="o">></span>
|
|
<span class="k">auto</span> <span class="nf">async_wait</span><span class="p">(</span><span class="n">native_exit_code_type</span> <span class="o">&</span><span class="n">exit_status</span><span class="p">,</span> <span class="n">WaitHandler</span> <span class="o">&&</span><span class="n">handler</span> <span class="o">=</span> <span class="n">net</span><span class="o">::</span><span class="n">default_completion_token_t</span><span class="o"><</span><span class="n">executor_type</span><span class="o">></span><span class="p">());</span>
|
|
<span class="p">};</span></code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="shell_hpp"><code>shell.hpp</code></h3>
|
|
<div id="shell" class="paragraph">
|
|
<p>This utility class parses command lines into tokens
|
|
and allows users to execute processes based on textual inputs.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>In v1, this was possible directly when starting a process,
|
|
but has been removed based on the security risks associated with this.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>By making the shell parsing explicitly, it encourages
|
|
a user to run a sanity check on the executable before launching it.</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="title">Example</div>
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"><span class="n">asio</span><span class="o">::</span><span class="n">io_context</span> <span class="n">ctx</span><span class="p">;</span>
|
|
|
|
<span class="k">auto</span> <span class="n">cmd</span> <span class="o">=</span> <span class="n">shell</span><span class="p">(</span><span class="s">"my-app --help"</span><span class="p">);</span>
|
|
<span class="k">auto</span> <span class="n">exe</span> <span class="o">=</span> <span class="n">cmd</span><span class="p">.</span><span class="n">exe</span><span class="p">();</span>
|
|
<span class="n">check_if_malicious</span><span class="p">(</span><span class="n">exe</span><span class="p">);</span>
|
|
|
|
<span class="n">process</span> <span class="n">proc</span><span class="p">{</span><span class="n">ctx</span><span class="p">,</span> <span class="n">exe</span><span class="p">,</span> <span class="n">cmd</span><span class="p">.</span><span class="n">args</span><span class="p">()};</span></code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"><span class="c1">/// Utility to parse commands</span>
|
|
<span class="k">struct</span> <span class="nc">shell</span>
|
|
<span class="p">{</span>
|
|
<span class="n">shell</span><span class="p">()</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Char</span><span class="p">,</span> <span class="k">typename</span> <span class="nc">Traits</span><span class="p">></span>
|
|
<span class="n">shell</span><span class="p">(</span><span class="n">basic_string_view</span><span class="o"><</span><span class="n">Char</span><span class="p">,</span> <span class="n">Traits</span><span class="o">></span> <span class="n">input</span><span class="p">);</span>
|
|
|
|
<span class="n">shell</span><span class="p">(</span><span class="n">basic_cstring_ref</span><span class="o"><</span><span class="n">char_type</span><span class="o">></span> <span class="n">input</span><span class="p">);</span>
|
|
<span class="n">shell</span><span class="p">(</span><span class="k">const</span> <span class="n">shell</span> <span class="o">&</span><span class="p">)</span> <span class="o">=</span> <span class="k">delete</span><span class="p">;</span>
|
|
<span class="n">shell</span><span class="p">(</span><span class="n">shell</span> <span class="o">&&</span> <span class="n">lhs</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</span>
|
|
<span class="n">shell</span><span class="o">&</span> <span class="k">operator</span><span class="o">=</span><span class="p">(</span><span class="k">const</span> <span class="n">shell</span> <span class="o">&</span><span class="p">)</span> <span class="o">=</span> <span class="k">delete</span><span class="p">;</span>
|
|
<span class="n">shell</span><span class="o">&</span> <span class="k">operator</span><span class="o">=</span><span class="p">(</span><span class="n">shell</span> <span class="o">&&</span> <span class="n">lhs</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</span>
|
|
|
|
|
|
<span class="c1">// the length of the parsed shell, including the executable</span>
|
|
<span class="kt">int</span> <span class="n">argc</span><span class="p">()</span> <span class="k">const</span> <span class="p">;</span>
|
|
<span class="n">char_type</span><span class="o">**</span> <span class="n">argv</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
|
|
<span class="n">char_type</span><span class="o">**</span> <span class="n">begin</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="n">char_type</span><span class="o">**</span> <span class="n">end</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
|
|
<span class="kt">bool</span> <span class="n">empty</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">size</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
|
|
<span class="c1">// Native representation of the arguments to be used - excluding the executable</span>
|
|
<span class="n">args_type</span> <span class="n">args</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Environment</span> <span class="o">=</span> <span class="n">environment</span><span class="o">::</span><span class="n">current_view</span><span class="p">></span>
|
|
<span class="n">filesystem</span><span class="o">::</span><span class="n">path</span> <span class="n">exe</span><span class="p">(</span><span class="n">Environment</span> <span class="o">&&</span> <span class="n">env</span> <span class="o">=</span> <span class="n">environment</span><span class="o">::</span><span class="n">current</span><span class="p">())</span> <span class="k">const</span><span class="p">;</span>
|
|
<span class="p">};</span></code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="start_dir_hpp"><code>start_dir.hpp</code></h3>
|
|
<div id="start_dir" class="listingblock">
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"><span class="c1">/// Initializer for the starting directory of a subprocess to be launched.</span>
|
|
<span class="k">struct</span> <span class="nc">process_start_dir</span>
|
|
<span class="p">{</span>
|
|
<span class="n">filesystem</span><span class="o">::</span><span class="n">path</span> <span class="n">start_dir</span><span class="p">;</span>
|
|
|
|
<span class="n">process_start_dir</span><span class="p">(</span><span class="n">filesystem</span><span class="o">::</span><span class="n">path</span> <span class="n">start_dir</span><span class="p">);</span>
|
|
<span class="p">{</span>
|
|
<span class="p">}</span>
|
|
<span class="p">};</span></code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="stdio_hpp"><code>stdio.hpp</code></h3>
|
|
<div id="stdio" class="literalblock">
|
|
<div class="content">
|
|
<pre> The initializer for the stdio of a subprocess
|
|
The subprocess stdio initializer has three members:</pre>
|
|
</div>
|
|
</div>
|
|
<div class="ulist">
|
|
<ul>
|
|
<li>
|
|
<p>in for stdin</p>
|
|
</li>
|
|
<li>
|
|
<p>out for stdout</p>
|
|
</li>
|
|
<li>
|
|
<p>err for stderr</p>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>If the initializer is present all three will be set for the subprocess.
|
|
By default they will inherit the stdio handles from the parent process.
|
|
This means that this will forward stdio to the subprocess:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"><span class="n">asio</span><span class="o">::</span><span class="n">io_context</span> <span class="n">ctx</span><span class="p">;</span>
|
|
<span class="n">v2</span><span class="o">::</span><span class="n">process</span> <span class="nf">proc</span><span class="p">(</span><span class="n">ctx</span><span class="p">,</span> <span class="s">"/bin/bash"</span><span class="p">,</span> <span class="p">{},</span> <span class="n">v2</span><span class="o">::</span><span class="n">process_stdio</span><span class="p">{});</span></code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>No constructors are provided in order to support designated initializers
|
|
in later version of C++.</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"><span class="n">asio</span><span class="o">::</span><span class="n">io_context</span> <span class="n">ctx</span><span class="p">;</span>
|
|
|
|
<span class="c1">/// C++17</span>
|
|
<span class="n">v2</span><span class="o">::</span><span class="n">process</span> <span class="nf">proc17</span><span class="p">(</span><span class="n">ctx</span><span class="p">,</span> <span class="s">"/bin/bash"</span><span class="p">,</span> <span class="p">{},</span> <span class="n">v2</span><span class="o">::</span><span class="n">process_stdio</span><span class="p">{.</span><span class="n">err</span><span class="o">=</span><span class="nb">nullptr</span><span class="p">});</span>
|
|
<span class="c1">/// C++11 & C++14</span>
|
|
<span class="n">v2</span><span class="o">::</span><span class="n">process</span> <span class="nf">proc17</span><span class="p">(</span><span class="n">ctx</span><span class="p">,</span> <span class="s">"/bin/bash"</span><span class="p">,</span> <span class="p">{},</span> <span class="n">v2</span><span class="o">::</span><span class="n">process_stdio</span><span class="p">{</span> <span class="p">{},</span> <span class="p">{},</span> <span class="nb">nullptr</span><span class="p">});</span></code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>Valid initializers for any stdio are:</p>
|
|
</div>
|
|
<div class="ulist">
|
|
<ul>
|
|
<li>
|
|
<p><code>std::nullptr_t</code> assigning a null-device</p>
|
|
</li>
|
|
<li>
|
|
<p><code>FILE*</code> any open file, including <code>stdin</code>, <code>stdout</code> and <code>stderr</code></p>
|
|
</li>
|
|
<li>
|
|
<p><code>native_handle</code> any native file handle (<code>HANDLE</code> on windows) or file descriptor (<code>int</code> on posix)</p>
|
|
</li>
|
|
<li>
|
|
<p>any io-object with a <code>.native_handle()</code> function that is compatible with the above. E.g. a <code>asio::ip::tcp::socket</code>, or a pipe object.</p>
|
|
</li>
|
|
<li>
|
|
<p>a filesystem::path, which will open a readable or writable depending on the direction of the stream</p>
|
|
</li>
|
|
<li>
|
|
<p>an <code>asio::basic_writeable_pipe</code> for stdin or <code>asio::basic_readable_pipe</code> for stderr/stdout.</p>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>When passing a <code>FILE*</code>, a <code>native_handle</code> or an io-object with a <code>native_handle</code>,
|
|
the initializer will assign the handle as is to the child process.
|
|
That is the file descriptor/handle gets cloned into the subprocess and used without modification.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>When passing a filesystem::path, the initializer will attempt to open the file and then pass the handle
|
|
to the subprocess.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>When passing a <code>readable_pipe</code> to stdout/stderr or a <code>writable_pipe</code> to stdin by reference,
|
|
the initializer to create the other side of the pipe (<code>writable_pipe</code> for stdout/stderr, <code>readable_pipe</code> for <code>stdin</code>),
|
|
connect the pair and pass the native_handle to the child process.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>That is, these two are equivalent:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="title">Implicit construction of the readable pipe.</div>
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"><span class="n">asio</span><span class="o">::</span><span class="n">io_context</span> <span class="n">ctx</span><span class="p">;</span>
|
|
<span class="n">asio</span><span class="o">::</span><span class="n">writable_pipe</span> <span class="n">wp</span><span class="p">{</span><span class="n">ctx</span><span class="p">};</span>
|
|
<span class="c1">// create a readable pipe internally and connect it to wp</span>
|
|
<span class="n">process</span> <span class="n">proc</span><span class="p">{</span><span class="n">ctx</span><span class="p">,</span> <span class="s">"/bin/bash"</span><span class="p">,</span> <span class="p">{},</span> <span class="n">process_stdio</span><span class="p">{.</span><span class="n">in</span><span class="o">=</span><span class="n">wp</span><span class="p">}};</span>
|
|
|
|
<span class="c1">// create it explicitly</span>
|
|
<span class="p">{</span>
|
|
<span class="c1">// the pipe the child process reads from</span>
|
|
<span class="n">asio</span><span class="o">::</span><span class="n">readable_pipe</span> <span class="n">rp</span><span class="p">{</span><span class="n">ctx</span><span class="p">};</span>
|
|
<span class="n">asio</span><span class="o">::</span><span class="n">connect_pipe</span><span class="p">(</span><span class="n">rp</span><span class="p">,</span> <span class="n">wp</span><span class="p">);</span>
|
|
<span class="c1">// `rp.native_handle()` will be assigned to the child processes stdin</span>
|
|
<span class="n">process</span> <span class="n">proc</span><span class="p">{</span><span class="n">ctx</span><span class="p">,</span> <span class="s">"/bin/bash"</span><span class="p">,</span> <span class="p">{},</span> <span class="n">process_stdio</span><span class="p">{.</span><span class="n">in</span><span class="o">=</span><span class="n">rp</span><span class="p">}};</span>
|
|
<span class="n">rp</span><span class="p">.</span><span class="n">close</span><span class="p">();</span> <span class="c1">// close it so the pipe closes when the `proc exits.</span>
|
|
<span class="p">}</span></code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The explicit version allows you to assign the same <code>writable_pipe</code> to <code>stdout</code> and <code>stderr</code>:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"><span class="c1">// the pipe the parent process reads from and both</span>
|
|
<span class="c1">// stderr & stdout of the child process write to</span>
|
|
<span class="n">asio</span><span class="o">::</span><span class="n">readable_pipe</span> <span class="n">rp</span><span class="p">{</span><span class="n">ctx</span><span class="p">};</span>
|
|
<span class="n">asio</span><span class="o">::</span><span class="n">writable_pipe</span> <span class="n">wp</span><span class="p">{</span><span class="n">ctx</span><span class="p">};</span>
|
|
<span class="n">asio</span><span class="o">::</span><span class="n">connect_pipe</span><span class="p">(</span><span class="n">rp</span><span class="p">,</span> <span class="n">wp</span><span class="p">);</span>
|
|
<span class="n">process</span> <span class="n">proc</span><span class="p">{</span><span class="n">ctx</span><span class="p">,</span> <span class="s">"/bin/bash"</span><span class="p">,</span> <span class="p">{},</span> <span class="n">process_stdio</span><span class="p">{.</span><span class="n">out</span><span class="o">=</span><span class="n">wp</span><span class="p">,</span> <span class="p">.</span><span class="n">err</span><span class="o">=</span><span class="n">wp</span><span class="p">}};</span>
|
|
<span class="n">wp</span><span class="p">.</span><span class="n">close</span><span class="p">();</span> <span class="c1">// close it so the pipe closes when the `proc exits.</span></code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="admonitionblock note">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-note" title="Note"></i>
|
|
</td>
|
|
<td class="content">
|
|
If the child writes to a pipe, the parent reads from it et vice versa.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"><span class="c1">/// The initializer for the stdio of a subprocess</span>
|
|
<span class="k">struct</span> <span class="nc">process_stdio</span>
|
|
<span class="p">{</span>
|
|
<span class="n">__implementation_defined__</span> <span class="n">in</span><span class="p">;</span>
|
|
<span class="n">__implementation_defined__</span> <span class="n">out</span><span class="p">;</span>
|
|
<span class="n">__implementation_defined__</span> <span class="n">err</span><span class="p">;</span>
|
|
<span class="p">};</span></code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="ext_2"><code>ext</code></h3>
|
|
<div class="paragraph">
|
|
<p>The headers in <code>process/ext</code> provides features to obtain information about third part processes.</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"><span class="c1">// Get the cmd line used to launche the process</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Executor</span><span class="p">></span>
|
|
<span class="n">shell</span> <span class="nf">cmd</span><span class="p">(</span><span class="n">basic_process_handle</span><span class="o"><</span><span class="n">Executor</span><span class="o">></span> <span class="o">&</span> <span class="n">handle</span><span class="p">,</span> <span class="n">error_code</span> <span class="o">&</span> <span class="n">ec</span><span class="p">);</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Executor</span><span class="p">></span>
|
|
<span class="n">shell</span> <span class="nf">cmd</span><span class="p">(</span><span class="n">basic_process_handle</span><span class="o"><</span><span class="n">Executor</span><span class="o">></span> <span class="o">&</span> <span class="n">handle</span><span class="p">);</span>
|
|
<span class="n">shell</span> <span class="nf">cmd</span><span class="p">(</span><span class="n">pid_type</span> <span class="n">pid</span><span class="p">,</span> <span class="n">error_code</span> <span class="o">&</span> <span class="n">ec</span><span class="p">);</span>
|
|
<span class="n">shell</span> <span class="nf">cmd</span><span class="p">(</span><span class="n">pid_type</span> <span class="n">pid</span><span class="p">);</span>
|
|
|
|
|
|
<span class="c1">// Get the current working directory of the process.</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Executor</span><span class="p">></span>
|
|
<span class="n">filesystem</span><span class="o">::</span><span class="n">path</span> <span class="nf">cwd</span><span class="p">(</span><span class="n">basic_process_handle</span><span class="o"><</span><span class="n">Executor</span><span class="o">></span> <span class="o">&</span> <span class="n">handle</span><span class="p">,</span> <span class="n">error_code</span> <span class="o">&</span> <span class="n">ec</span><span class="p">);</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Executor</span><span class="p">></span>
|
|
<span class="n">filesystem</span><span class="o">::</span><span class="n">path</span> <span class="nf">cwd</span><span class="p">(</span><span class="n">basic_process_handle</span><span class="o"><</span><span class="n">Executor</span><span class="o">></span> <span class="o">&</span> <span class="n">handle</span><span class="p">)</span>
|
|
<span class="n">filesystem</span><span class="o">::</span><span class="n">path</span> <span class="n">cwd</span><span class="p">(</span><span class="n">pid_type</span> <span class="n">pid</span><span class="p">,</span> <span class="n">error_code</span> <span class="o">&</span> <span class="n">ec</span><span class="p">);</span>
|
|
<span class="n">filesystem</span><span class="o">::</span><span class="n">path</span> <span class="nf">cwd</span><span class="p">(</span><span class="n">pid_type</span> <span class="n">pid</span><span class="p">);</span>
|
|
|
|
|
|
<span class="c1">// Get the current environment of the process.</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Executor</span><span class="p">></span>
|
|
<span class="n">env_view</span> <span class="nf">cwd</span><span class="p">(</span><span class="n">basic_process_handle</span><span class="o"><</span><span class="n">Executor</span><span class="o">></span> <span class="o">&</span> <span class="n">handle</span><span class="p">,</span> <span class="n">error_code</span> <span class="o">&</span> <span class="n">ec</span><span class="p">);</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Executor</span><span class="p">></span>
|
|
<span class="n">env_view</span> <span class="nf">cwd</span><span class="p">(</span><span class="n">basic_process_handle</span><span class="o"><</span><span class="n">Executor</span><span class="o">></span> <span class="o">&</span> <span class="n">handle</span><span class="p">)</span>
|
|
<span class="n">env_view</span> <span class="n">env</span><span class="p">(</span><span class="n">pid_type</span> <span class="n">pid</span><span class="p">,</span> <span class="n">error_code</span> <span class="o">&</span> <span class="n">ec</span><span class="p">);</span>
|
|
<span class="n">env_view</span> <span class="nf">env</span><span class="p">(</span><span class="n">pid_type</span> <span class="n">pid</span><span class="p">);</span>
|
|
|
|
|
|
<span class="c1">// Get the executable of the process.</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Executor</span><span class="p">></span>
|
|
<span class="n">filesystem</span><span class="o">::</span><span class="n">path</span> <span class="nf">exe</span><span class="p">(</span><span class="n">basic_process_handle</span><span class="o"><</span><span class="n">Executor</span><span class="o">></span> <span class="o">&</span> <span class="n">handle</span><span class="p">,</span> <span class="n">error_code</span> <span class="o">&</span> <span class="n">ec</span><span class="p">);</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Executor</span><span class="p">></span>
|
|
<span class="n">filesystem</span><span class="o">::</span><span class="n">path</span> <span class="nf">exe</span><span class="p">(</span><span class="n">basic_process_handle</span><span class="o"><</span><span class="n">Executor</span><span class="o">></span> <span class="o">&</span> <span class="n">handle</span><span class="p">)</span>
|
|
<span class="n">filesystem</span><span class="o">::</span><span class="n">path</span> <span class="n">exe</span><span class="p">(</span><span class="n">pid_type</span> <span class="n">pid</span><span class="p">,</span> <span class="n">error_code</span> <span class="o">&</span> <span class="n">ec</span><span class="p">);</span>
|
|
<span class="n">filesystem</span><span class="o">::</span><span class="n">path</span> <span class="nf">exe</span><span class="p">(</span><span class="n">pid_type</span> <span class="n">pid</span><span class="p">);</span></code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="admonitionblock warning">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-warning" title="Warning"></i>
|
|
</td>
|
|
<td class="content">
|
|
The function may fail with "operation_not_supported" on some niche platforms.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="admonitionblock note">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-note" title="Note"></i>
|
|
</td>
|
|
<td class="content">
|
|
On windows overloads taking a <code>HANDLE</code> are also available.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="posixbind_fd_hpp"><code>posix/bind_fd.hpp</code></h3>
|
|
<div class="paragraph">
|
|
<p><code>bind_fd</code> is a utility class to bind a file descriptor to an explicit file descriptor for the child process.</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"><span class="k">struct</span> <span class="nc">bind_fd</span>
|
|
<span class="p">{</span>
|
|
<span class="c1">// Inherit file descriptor with the same value.</span>
|
|
<span class="cm">/*
|
|
* This will pass descriptor 42 as 42 to the child process:
|
|
* @code
|
|
* process p{"test", {}, posix::bind_fd(42)};
|
|
* @endcode
|
|
*/</span>
|
|
<span class="n">bind_fd</span><span class="p">(</span><span class="kt">int</span> <span class="n">target</span><span class="p">);</span>
|
|
|
|
<span class="c1">// Inherit an asio io-object as a given file descriptor to the child process.</span>
|
|
<span class="cm">/*
|
|
* This will pass the tcp::socket, as 42 to the child process:
|
|
* @code
|
|
* extern tcp::socket sock;
|
|
* process p{"test", {}, posix::bind_fd(42, sock)};
|
|
* @endcode
|
|
*/</span>
|
|
|
|
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="nc">Stream</span><span class="p">></span>
|
|
<span class="n">bind_fd</span><span class="p">(</span><span class="kt">int</span> <span class="n">target</span><span class="p">,</span> <span class="n">Stream</span> <span class="o">&&</span> <span class="n">str</span><span class="p">);</span>
|
|
|
|
<span class="c1">// Inherit a `FILE` as a given file descriptor to the child process.</span>
|
|
<span class="cm">/* This will pass the given `FILE*`, as 42 to the child process:
|
|
|
|
process p{"test", {}, posix::bind_fd(42, stderr)};
|
|
|
|
*/</span>
|
|
<span class="n">bind_fd</span><span class="p">(</span><span class="kt">int</span> <span class="n">target</span><span class="p">,</span> <span class="kt">FILE</span> <span class="o">*</span> <span class="n">f</span><span class="p">);</span>
|
|
|
|
<span class="c1">// Inherit a file descriptor with as a different value.</span>
|
|
<span class="cm">/* This will pass 24 as 42 to the child process:
|
|
|
|
process p{"test", {}, posix::bind_fd(42, 24)};
|
|
|
|
*/</span>
|
|
<span class="n">bind_fd</span><span class="p">(</span><span class="kt">int</span> <span class="n">target</span><span class="p">,</span> <span class="kt">int</span> <span class="n">fd</span><span class="p">);</span>
|
|
|
|
<span class="c1">// Inherit a null device as a set descriptor.</span>
|
|
<span class="cm">/* This will a null device as 42 to the child process:
|
|
|
|
process p{"test", {}, posix::bind_fd(42, nullptr)};
|
|
|
|
*/</span>
|
|
<span class="n">bind_fd</span><span class="p">(</span><span class="kt">int</span> <span class="n">target</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">nullptr_t</span><span class="p">);</span>
|
|
|
|
<span class="c1">// Inherit a newly opened-file as a set descriptor.</span>
|
|
<span class="cm">/* This will pass a descriptor to "extra-output.txt" as 42 to the child process:
|
|
|
|
process p{"test", {}, posix::bind_fd(42, "extra-output.txt")};
|
|
|
|
*/</span>
|
|
<span class="n">bind_fd</span><span class="p">(</span><span class="kt">int</span> <span class="n">target</span><span class="p">,</span> <span class="k">const</span> <span class="n">filesystem</span><span class="o">::</span><span class="n">path</span> <span class="o">&</span> <span class="n">pth</span><span class="p">,</span> <span class="kt">int</span> <span class="n">flags</span> <span class="o">=</span> <span class="n">O_RDWR</span> <span class="o">|</span> <span class="n">O_CREAT</span><span class="p">);</span>
|
|
|
|
<span class="p">};</span></code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>Using <code>bind_fd</code> can be used to inherit file descriptors explicitly, because no unused one will be.</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"></code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="windowscreation_flags_hpp"><code>windows/creation_flags.hpp</code></h3>
|
|
<div class="paragraph">
|
|
<p>Creation flags allows explicitly setting <code>dwFlags</code></p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"><span class="c1">// An initializer to add to the dwFlags in the startup-info</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="n">DWORD</span> <span class="n">Flags</span><span class="p">></span>
|
|
<span class="k">struct</span> <span class="nc">process_creation_flags</span><span class="p">;</span>
|
|
|
|
<span class="c1">// A flag to create a new process group. Necessary to allow interrupts for the subprocess.</span>
|
|
<span class="k">constexpr</span> <span class="k">static</span> <span class="n">process_creation_flags</span><span class="o"><</span><span class="n">CREATE_NEW_PROCESS_GROUP</span><span class="o">></span> <span class="n">create_new_process_group</span><span class="p">;</span>
|
|
|
|
<span class="c1">// Breakaway from the current job object.</span>
|
|
<span class="k">constexpr</span> <span class="k">static</span> <span class="n">process_creation_flags</span><span class="o"><</span><span class="n">CREATE_BREAKAWAY_FROM_JOB</span><span class="o">></span> <span class="n">create_breakaway_from_job</span><span class="p">;</span>
|
|
<span class="c1">// Allocate a new console.</span>
|
|
<span class="k">constexpr</span> <span class="k">static</span> <span class="n">process_creation_flags</span><span class="o"><</span><span class="n">CREATE_NEW_CONSOLE</span><span class="o">></span> <span class="n">create_new_console</span><span class="p">;</span></code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The flags can be used like this:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"><span class="n">process</span> <span class="n">p</span><span class="p">{</span><span class="s">"C:</span><span class="se">\\</span><span class="s">not-a-virus.exe"</span><span class="p">,</span> <span class="p">{},</span> <span class="n">process</span><span class="o">::</span><span class="n">windows</span><span class="o">::</span><span class="n">create_new_console</span><span class="p">};</span></code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="windowsshow_window_hpp"><code>windows/show_window.hpp</code></h3>
|
|
<div class="paragraph">
|
|
<p>Creation flags allows explicitly setting <code>wShowWindow</code> options</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"><span class="c1">/// A templated initializer to set wShowWindow flags.</span>
|
|
<span class="k">template</span><span class="o"><</span><span class="n">DWORD</span> <span class="n">Flags</span><span class="p">></span>
|
|
<span class="k">struct</span> <span class="nc">process_show_window</span><span class="p">;</span>
|
|
|
|
<span class="c1">//Hides the window and activates another window.</span>
|
|
<span class="k">constexpr</span> <span class="k">static</span> <span class="n">process_show_window</span><span class="o"><</span><span class="n">SW_HIDE</span> <span class="o">></span> <span class="n">show_window_hide</span><span class="p">;</span>
|
|
<span class="c1">//Activates the window and displays it as a maximized window.</span>
|
|
<span class="k">constexpr</span> <span class="k">static</span> <span class="n">process_show_window</span><span class="o"><</span><span class="n">SW_SHOWMAXIMIZED</span> <span class="o">></span> <span class="n">show_window_maximized</span><span class="p">;</span>
|
|
<span class="c1">//Activates the window and displays it as a minimized window.</span>
|
|
<span class="k">constexpr</span> <span class="k">static</span> <span class="n">process_show_window</span><span class="o"><</span><span class="n">SW_SHOWMINIMIZED</span> <span class="o">></span> <span class="n">show_window_minimized</span><span class="p">;</span>
|
|
<span class="c1">//Displays the window as a minimized window. This value is similar to `minimized`, except the window is not activated.</span>
|
|
<span class="k">constexpr</span> <span class="k">static</span> <span class="n">process_show_window</span><span class="o"><</span><span class="n">SW_SHOWMINNOACTIVE</span><span class="o">></span> <span class="n">show_window_minimized_not_active</span><span class="p">;</span>
|
|
<span class="c1">//Displays a window in its most recent size and position. This value is similar to show_normal`, except that the window is not activated.</span>
|
|
<span class="k">constexpr</span> <span class="k">static</span> <span class="n">process_show_window</span><span class="o"><</span><span class="n">SW_SHOWNOACTIVATE</span> <span class="o">></span> <span class="n">show_window_not_active</span><span class="p">;</span>
|
|
<span class="c1">//Activates and displays a window. If the window is minimized or maximized, the system restores it to its original size and position. An application should specify this flag when displaying the window for the first time.</span>
|
|
<span class="k">constexpr</span> <span class="k">static</span> <span class="n">process_show_window</span><span class="o"><</span><span class="n">SW_SHOWNORMAL</span> <span class="o">></span> <span class="n">show_window_normal</span><span class="p">;</span></code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The flags can be used like this:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"><span class="n">process</span> <span class="n">p</span><span class="p">{</span><span class="s">"C:</span><span class="se">\\</span><span class="s">not-a-virus.exe"</span><span class="p">,</span> <span class="p">{},</span> <span class="n">process</span><span class="o">::</span><span class="n">windows</span><span class="o">::</span><span class="n">show_window_minimized</span><span class="p">};</span></code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect1">
|
|
<h2 id="version_2">Version 2</h2>
|
|
<div class="sectionbody">
|
|
<div class="paragraph">
|
|
<p>Boost.process V2 is an redesign of boost.process, based on previous
|
|
design mistakes & improved system APIs.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The major changes are</p>
|
|
</div>
|
|
<div class="ulist">
|
|
<ul>
|
|
<li>
|
|
<p>Simplified interface</p>
|
|
</li>
|
|
<li>
|
|
<p>Reliance on pidfd_open on linux</p>
|
|
</li>
|
|
<li>
|
|
<p>Full asio integration</p>
|
|
</li>
|
|
<li>
|
|
<p>Removed unreliable functionality</p>
|
|
</li>
|
|
<li>
|
|
<p>UTF8 Support</p>
|
|
</li>
|
|
<li>
|
|
<p>separate compilation</p>
|
|
</li>
|
|
<li>
|
|
<p>fd safe by default</p>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>Version 2 is now the default. In order to discourage usage of the deprecated v1, it’s documentation has been removed.</p>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="simplified_interface">Simplified Interface</h3>
|
|
<div class="paragraph">
|
|
<p>In process v1 one can define partial settings in the constructor of the process,
|
|
which has lead to a small DSL.</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"><span class="n">child</span> <span class="n">c</span><span class="p">{</span><span class="n">exe</span><span class="o">=</span><span class="s">"test"</span><span class="p">,</span> <span class="n">args</span><span class="o">+=</span><span class="s">"--help"</span><span class="p">,</span> <span class="n">std_in</span> <span class="o"><</span> <span class="n">null</span><span class="p">(),</span> <span class="n">env</span><span class="p">[</span><span class="s">"FOO"</span><span class="p">]</span> <span class="o">+=</span> <span class="s">"BAR"</span><span class="p">};</span></code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>While this looks fancy at first, it really does not scale well with more parameters.
|
|
For process v2, the interfaces is simple:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="rouge highlight"><code data-lang="cpp"><span class="k">extern</span> <span class="n">std</span><span class="o">::</span><span class="n">unordered_map</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">></span> <span class="n">my_env</span><span class="p">;</span>
|
|
<span class="k">extern</span> <span class="n">asio</span><span class="o">::</span><span class="n">io_context</span> <span class="n">ctx</span><span class="p">;</span>
|
|
<span class="n">process</span> <span class="nf">proc</span><span class="p">(</span><span class="n">ctx</span><span class="p">,</span> <span class="s">"./test"</span><span class="p">,</span> <span class="p">{</span><span class="s">"--help"</span><span class="p">},</span> <span class="n">process_stdio</span><span class="p">{</span><span class="nb">nullptr</span><span class="p">,</span> <span class="p">{},</span> <span class="p">{}},</span> <span class="n">process_environment</span><span class="p">(</span><span class="n">my_env</span><span class="p">));</span></code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>Every initializer addresses one logical component (e.g. stdio) instead of multiple ones accumulating.
|
|
Furthermore, every process has a path and arguments, instead of a confusing mixture of cmd-style and
|
|
exe-args that can be randomly spread out.</p>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="pidfd_open"><code>pidfd_open</code></h3>
|
|
<div class="paragraph">
|
|
<p>Since process v1 came out, linux has moved along and added [pidfd_open](<a href="https://man7.org/linux/man-pages/man2/pidfd_open.2.html" class="bare">https://man7.org/linux/man-pages/man2/pidfd_open.2.html</a>)
|
|
which allows users to obtain a descriptor for a process.
|
|
This is much more reliable since it is not as easy to miss as a <code>SIGCHLD</code>.
|
|
Windows has provided `HANDLE`s for processes all along.
|
|
Unless the OS doesn’t support it, process v2 will use file descriptors and handles to implement waiting
|
|
for processes.</p>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="full_asio_integration">Full asio integration</h3>
|
|
<div class="paragraph">
|
|
<p>Process v1 aimed to make asio optional, but synchronous IO with subprocesses usually means one is begging
|
|
for deadlocks.
|
|
Since asio added pipes in boost 1.78, boost process V2 is fully asio based and uses it’s pipes and
|
|
file-handles for the subprocess.</p>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="unreliable_functionality">Unreliable functionality</h3>
|
|
<div class="paragraph">
|
|
<p>Certain parts of boost.process were not as reliable as they should’ve been.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>This concerns especially the <code>wait_for</code> and <code>wait_until</code> functions on the process.
|
|
The latter are easy to do on windows, but posix does not provide an API for this.
|
|
Thus the wait_for used signals or fork, which was all but safe.
|
|
Since process v2 is based on asio and thus supports cancellation,
|
|
a wait_for can now safely be implemented with an async_wait + timeout.</p>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="utf_8">UTF-8</h3>
|
|
<div class="paragraph">
|
|
<p>Instead of using ascii-APIs on windows, process V2 just assumes UTF-8 everywhere
|
|
and uses the UTF-16 APIs.</p>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="fd_safe_by_default">Fd safe by default</h3>
|
|
<div class="paragraph">
|
|
<p>While not a problem on windows (since HANDLEs get manually enabled for inheritance),
|
|
posix systems create a problem with inheriting file handles by default.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>Process V2 will automatically close all non-whitelisted descriptors,
|
|
without needing any option to enable it.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect1">
|
|
<h2 id="acknowledgements">Acknowledgements</h2>
|
|
<div class="sectionbody">
|
|
<div class="paragraph">
|
|
<p>The first Boost.Process draft was created in 2006. A lof of people have worked on various drafts since then. Especially Merino Vidal, Ilya Sokolov and Felipe Tanus spent a lot of time working on early drafts. They influenced Boost.Process over the years and wrote code which, to various extents, is still around in the library today.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The design of earlier versions of Boost.Process was not always satisfying. In 2011 Jeff Flinn proposed the executor and initializer concepts Boost.Process is based on today. Without Jeff’s idea the overall design of Boost.Process would not look like it does today.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>A special thank you goes to [<a href="http://www.intra2net.com/(Intra2net" class="bare">http://www.intra2net.com/(Intra2net</a> AG) (especially Thomas Jarosch) who sponsored a project to support the development of Boost.Process. It was this sponsorship which made it possible to create a new Boost.Process version in 2012.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>Great thanks also goes to Boris Schaeling, who despite having boost.process rejected, went on to work on it and maintained it up until this day and participated in the development of the current version.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>Many Thanks, to [<a href="https://github.com/samuelvenable" class="bare">https://github.com/samuelvenable</a>](Samuel Venable) for contributing the <a href="#v2::ext">[v2::ext]</a> functionality and all the research that went into it.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="footer">
|
|
<div id="footer-text">
|
|
Version 2.0<br>
|
|
Last updated 2026-04-15 14:38:59 UTC
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html> |