TP-systeme-exploitation-cen.../TP1/processus.html
2023-06-20 20:57:09 +02:00

1929 lines
285 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" data-darkreader-mode="dynamic" data-darkreader-scheme="dark" lang="fr"><head><style class="darkreader darkreader--fallback" media="screen"></style><style class="darkreader darkreader--text" media="screen"></style><style class="darkreader darkreader--invert" media="screen">.jfk-bubble.gtx-bubble, .captcheck_answer_label > input + img, span#closed_text > img[src^="https://www.gstatic.com/images/branding/googlelogo"], span[data-href^="https://www.hcaptcha.com/"] > #icon, #bit-notification-bar-iframe, embed[type="application/pdf"] {
filter: invert(100%) hue-rotate(180deg) contrast(90%) !important;
}</style><style class="darkreader darkreader--inline" media="screen">[data-darkreader-inline-bgcolor] {
background-color: var(--darkreader-inline-bgcolor) !important;
}
[data-darkreader-inline-bgimage] {
background-image: var(--darkreader-inline-bgimage) !important;
}
[data-darkreader-inline-border] {
border-color: var(--darkreader-inline-border) !important;
}
[data-darkreader-inline-border-bottom] {
border-bottom-color: var(--darkreader-inline-border-bottom) !important;
}
[data-darkreader-inline-border-left] {
border-left-color: var(--darkreader-inline-border-left) !important;
}
[data-darkreader-inline-border-right] {
border-right-color: var(--darkreader-inline-border-right) !important;
}
[data-darkreader-inline-border-top] {
border-top-color: var(--darkreader-inline-border-top) !important;
}
[data-darkreader-inline-boxshadow] {
box-shadow: var(--darkreader-inline-boxshadow) !important;
}
[data-darkreader-inline-color] {
color: var(--darkreader-inline-color) !important;
}
[data-darkreader-inline-fill] {
fill: var(--darkreader-inline-fill) !important;
}
[data-darkreader-inline-stroke] {
stroke: var(--darkreader-inline-stroke) !important;
}
[data-darkreader-inline-outline] {
outline-color: var(--darkreader-inline-outline) !important;
}
[data-darkreader-inline-stopcolor] {
stop-color: var(--darkreader-inline-stopcolor) !important;
}</style><style class="darkreader darkreader--variables" media="screen">:root {
--darkreader-neutral-background: #131516;
--darkreader-neutral-text: #d8d4cf;
--darkreader-selection-background: #004daa;
--darkreader-selection-text: #e8e6e3;
}</style><style class="darkreader darkreader--root-vars" media="screen"></style><script class="darkreader darkreader--proxy">(function injectProxy() {
document.dispatchEvent(new CustomEvent('__darkreader__inlineScriptsAllowed'));
const addRuleDescriptor = Object.getOwnPropertyDescriptor(CSSStyleSheet.prototype, 'addRule');
const insertRuleDescriptor = Object.getOwnPropertyDescriptor(CSSStyleSheet.prototype, 'insertRule');
const deleteRuleDescriptor = Object.getOwnPropertyDescriptor(CSSStyleSheet.prototype, 'deleteRule');
const removeRuleDescriptor = Object.getOwnPropertyDescriptor(CSSStyleSheet.prototype, 'removeRule');
const shouldWrapDocStyleSheets = location.hostname.endsWith('pushbullet.com');
const documentStyleSheetsDescriptor = shouldWrapDocStyleSheets ? Object.getOwnPropertyDescriptor(Document.prototype, 'styleSheets') : null;
const cleanUp = () => {
Object.defineProperty(CSSStyleSheet.prototype, 'addRule', addRuleDescriptor);
Object.defineProperty(CSSStyleSheet.prototype, 'insertRule', insertRuleDescriptor);
Object.defineProperty(CSSStyleSheet.prototype, 'deleteRule', deleteRuleDescriptor);
Object.defineProperty(CSSStyleSheet.prototype, 'removeRule', removeRuleDescriptor);
document.removeEventListener('__darkreader__cleanUp', cleanUp);
document.removeEventListener('__darkreader__addUndefinedResolver', addUndefinedResolver);
if (shouldWrapDocStyleSheets) {
Object.defineProperty(Document.prototype, 'styleSheets', documentStyleSheetsDescriptor);
}
};
const addUndefinedResolver = (e) => {
customElements.whenDefined(e.detail.tag).then(() => {
document.dispatchEvent(new CustomEvent('__darkreader__isDefined', { detail: { tag: e.detail.tag } }));
});
};
document.addEventListener('__darkreader__cleanUp', cleanUp);
document.addEventListener('__darkreader__addUndefinedResolver', addUndefinedResolver);
const updateSheetEvent = new Event('__darkreader__updateSheet');
function proxyAddRule(selector, style, index) {
addRuleDescriptor.value.call(this, selector, style, index);
if (this.ownerNode && !this.ownerNode.classList.contains('darkreader')) {
this.ownerNode.dispatchEvent(updateSheetEvent);
}
return -1;
}
function proxyInsertRule(rule, index) {
const returnValue = insertRuleDescriptor.value.call(this, rule, index);
if (this.ownerNode && !this.ownerNode.classList.contains('darkreader')) {
this.ownerNode.dispatchEvent(updateSheetEvent);
}
return returnValue;
}
function proxyDeleteRule(index) {
deleteRuleDescriptor.value.call(this, index);
if (this.ownerNode && !this.ownerNode.classList.contains('darkreader')) {
this.ownerNode.dispatchEvent(updateSheetEvent);
}
}
function proxyRemoveRule(index) {
removeRuleDescriptor.value.call(this, index);
if (this.ownerNode && !this.ownerNode.classList.contains('darkreader')) {
this.ownerNode.dispatchEvent(updateSheetEvent);
}
}
function proxyDocumentStyleSheets() {
const docSheets = documentStyleSheetsDescriptor.get.call(this);
const filtered = [...docSheets].filter((styleSheet) => {
return !styleSheet.ownerNode.classList.contains('darkreader');
});
return Object.setPrototypeOf(filtered, StyleSheetList.prototype);
}
Object.defineProperty(CSSStyleSheet.prototype, 'addRule', Object.assign({}, addRuleDescriptor, { value: proxyAddRule }));
Object.defineProperty(CSSStyleSheet.prototype, 'insertRule', Object.assign({}, insertRuleDescriptor, { value: proxyInsertRule }));
Object.defineProperty(CSSStyleSheet.prototype, 'deleteRule', Object.assign({}, deleteRuleDescriptor, { value: proxyDeleteRule }));
Object.defineProperty(CSSStyleSheet.prototype, 'removeRule', Object.assign({}, removeRuleDescriptor, { value: proxyRemoveRule }));
if (shouldWrapDocStyleSheets) {
Object.defineProperty(Document.prototype, 'styleSheets', Object.assign({}, documentStyleSheetsDescriptor, { get: proxyDocumentStyleSheets }));
}
})()</script><style class="darkreader darkreader--user-agent" media="screen">html {
background-color: #181a1b !important;
}
html, body, input, textarea, select, button {
background-color: #181a1b;
}
html, body, input, textarea, select, button {
border-color: #736b5e;
color: #e8e6e3;
}
a {
color: #3391ff;
}
table {
border-color: #545b5e;
}
::placeholder {
color: #b2aba1;
}
input:-webkit-autofill,
textarea:-webkit-autofill,
select:-webkit-autofill {
background-color: #555b00 !important;
color: #e8e6e3 !important;
}
::-webkit-scrollbar {
background-color: #202324;
color: #aba499;
}
::-webkit-scrollbar-thumb {
background-color: #454a4d;
}
::-webkit-scrollbar-thumb:hover {
background-color: #575e62;
}
::-webkit-scrollbar-thumb:active {
background-color: #484e51;
}
::-webkit-scrollbar-corner {
background-color: #181a1b;
}
* {
scrollbar-color: #454a4d #202324;
}
::selection {
background-color: #004daa !important;
color: #e8e6e3 !important;
}
::-moz-selection {
background-color: #004daa !important;
color: #e8e6e3 !important;
}</style>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Processus Unix</title>
<meta name="generator" content="Org-mode">
<meta name="author" content="Zouheir HAMROUNI">
<style type="text/css">
<!--/*-->
<![CDATA[/*><!--*/
.title { text-align: center;
margin-bottom: .2em; color: #4020A0;}
.subtitle { text-align: center;
font-size: medium;
font-weight: bold;
margin-top:0; }
.todo { font-family: monospace; color: red; }
.done { font-family: monospace; color: green; }
.priority { font-family: monospace; color: orange; }
.tag { background-color: #eee; font-family: monospace;
padding: 2px; font-size: 80%; font-weight: normal; }
.timestamp { color: #bebebe; }
.timestamp-kwd { color: #5f9ea0; }
.org-right { margin-left: auto; margin-right: 0px; text-align: right; }
.org-left { margin-left: 0px; margin-right: auto; text-align: left; }
.org-center { margin-left: auto; margin-right: auto; text-align: center; }
.underline { text-decoration: underline; }
#postamble p, #preamble p { font-size: 90%; margin: .2em; }
p.verse { margin-left: 3%; }
pre {
border: 1px solid #ccc;
box-shadow: 3px 3px 3px #eee;
padding: 4pt;
font-family: monospace;
font-size: 90%;
overflow: auto;
margin: 0em;
top-margin: 2em;
}
pre.src {
position: relative;
overflow: visible;
padding-top: 1.2em;
}
pre.src:before {
display: none;
position: absolute;
background-color: white;
top: -10px;
right: 10px;
padding: 2px;
border: 1px solid black;
}
pre.src:hover:before { display: inline;}
pre.src-sh:before { content: 'sh'; }
pre.src-bash:before { content: 'sh'; }
pre.src-emacs-lisp:before { content: 'Emacs Lisp'; }
pre.src-R:before { content: 'R'; }
pre.src-perl:before { content: 'Perl'; }
pre.src-java:before { content: 'Java'; }
pre.src-sql:before { content: 'SQL'; }
table { border-collapse:collapse; }
caption.t-above { caption-side: top; }
caption.t-bottom { caption-side: bottom; }
td, th { vertical-align:top; }
th.org-right { text-align: center; }
th.org-left { text-align: center; }
th.org-center { text-align: center; }
td.org-right { text-align: right; }
td.org-left { text-align: left; }
td.org-center { text-align: center; }
dt { font-weight: bold; }
.footpara { display: inline; }
.footdef { margin-bottom: 1em; }
.figure { padding: 1em; }
.figure p { text-align: center; }
.inlinetask {
padding: 10px;
border: 2px solid gray;
margin: 10px;
background: #ffffcc;
}
#org-div-home-and-up
{ text-align: right; font-size: 70%; white-space: nowrap; }
textarea { overflow-x: auto; }
.linenr { font-size: smaller }
.code-highlighted { background-color: #ffff00; }
.org-info-js_info-navigation { border-style: none; }
#org-info-js_console-label
{ font-size: 10px; font-weight: bold; white-space: nowrap; }
.org-info-js_search-highlight
{ background-color: #ffff00; color: #000000; font-weight: bold; }
/*]]>
</style><style class="darkreader darkreader--sync" media="screen"></style>
<style>
@media only screen and (min-width: 1024px) {
#table-of-contents {
position: fixed;
top: 0;
left: 0;
bottom: 0;
width: 36ex;
overflow-y: auto;
border-right: 1px solid #e8e8e8;
padding: 0 15px;
font-size: 14px;
background-color: #f0f0f0;
-webkit-overflow-scrolling: touch;
}
body {
position: absolute;
top: 0;
left: 20%;
width: 84ex;
margin-left: auto;
margin-right: auto;
text-align: justify;
hyphens: auto;
-moz-hyphens: auto;
-webkit-hyphens: auto;
-ms-hyphens: auto;
right: 0;
padding: 0 15px;
-webkit-overflow-scrolling: touch;
font-size: 14px;
}
}
@media only print {
#table-of-contents, #nav {
display: none;
}
}
@media only screen and (max-width: 1023px) {
#table-of-contents {
width: 100%;
top: 40px;
}
body {
text-align: justify;
hyphens: auto;
-moz-hyphens: auto;
-webkit-hyphens: auto;
-ms-hyphens: auto;
width: 84ex;
margin-left: auto;
margin-right: auto;
right: 0;
padding: 0 15px;
-webkit-overflow-scrolling: touch;
font-size: 14px;
}
}
@media (min-width: 768px) {
body {
max-width: 750px;
}
}
body {
font-family:Roboto,'Helvetica Neue',sans-serif;
}
.org-info-js_header-navigation > a,
.org-info-js_info-navigation a[accesskey],
.org-info-js_info-navigation > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(1) > span:nth-child(2) > a:nth-child(1)
{
font-size: 1ex;
border-radius: 10px;
padding: 5px;
margin-top: 5px;
margin-bottom: 5px;
background-color: #F9F9F9;
border: solid 1px #EFE9E9;
color: #804040;
text-decoration: none;
}
#table-of-contents ul {
padding: 0;
}
.toc-h1 {
margin-left: 0ex;
list-style-type: none;
}
.toc-h2 {
margin-left: 3ex;
list-style-type: none;
}
.toc-h3 {
margin-left: 6ex;
list-style-type: none;
}
a {
color: #202090;
}
#table-of-contents a,
.org-info-js_info-navigation a {
text-decoration: none;
}
#table-of-contents a:hover {
text-decoration: underline;
text-color: #502030;
}
#table-of-contents a:visited {
color: #d02010;
}
#table-of-contents a {
color: #101080;
}
#table-of-contents {
background-color: #FaFaFf;
}
#table-of-contents a.current, #table-of-contents .toc-active {
background-color: #f0e0d0;
}
pre.src, pre.example {
font-size: 90%;
overflow-y : scroll;
}
@media (max-width: 400px) {
pre.src, pre.example {
overflow-x: scroll;
}
}
code {
background: #F0A040;
border: solid 1px #E0E8E0;
padding-top: 0ex;
padding-bottom: 0ex;
padding-left: .1ex;
padding-right: .1ex;
font-size: 110%;
border-radius: 5px;
}
methode {
background: #F0F0F0;
border: solid 1px #E0E8E0;
padding-top: 0ex;
padding-bottom: 0ex;
padding-left: .1ex;
padding-right: .1ex;
font-size: 100%;
border-radius: 5px;
}
touche {
background: #A0A0A0;
border: solid 1px #101010;
padding-top: 0ex;
padding-bottom: 0ex;
padding-left: .4ex;
padding-right: .4ex;
font-size: 100%;
border-radius: 2px;
}
.encadreblanc {
border: solid;
border-radius: 0.5em;
margin: 0.1em;
border-width: 0.1em;
padding: 0.5em;
}
.jeudepiste {
border: solid;
border-radius: 0.5em;
border-color: #4060F0;
margin: 0.1em;
border-width: 0.1em;
padding: 0.5em;
background-color: #E0F0FF;
}
.conseil {
border: solid;
border-radius: 0.5em;
border-color: #80E060;
margin: 0.1em;
border-width: 0.1em;
padding: 0.5em;
background-color: #B0F0A0;
}
.clavier {
border: solid;
border-width: 0.1em;
border-radius: 0.5em;
padding: 0.2em;
display: inline-block;
}
.attention {
border-radius: 0.5em;
border:solid;
border-color: #F04010;
border-width: 0.1em;
padding: 0.5em;
margin: 0.1em;
background-color: #FFD080;
}
.interdit {
border-radius: 0.5em;
border:solid;
border-color: #F02010;
border-width: 0.1em;
padding: 0.5em;
margin: 0.1em;
background-color: #FFB090;
}
</style><style class="darkreader darkreader--sync" media="screen"></style>
<script type="text/javascript" src="processus_files/jquery.js"></script><meta name="darkreader" content="28a48d3bad4f3d1d6c9476d26e47a960"><style class="darkreader darkreader--override" media="screen">.vimvixen-hint {
background-color: #7b5300 !important;
border-color: #d8b013 !important;
color: #f3e8c8 !important;
}
::placeholder {
opacity: 0.5 !important;
}
a[href="https://coinmarketcap.com/"] > svg[width="94"][height="16"] > path {
fill: var(--darkreader-neutral-text) !important;
}
#edge-translate-panel-body {
color: var(--darkreader-neutral-text) !important;
}</style>
<script type="text/javascript">
$(document).ready(function(){
var $contenu = $('.toggle_container');
$contenu.hide();
$('h4.trigger').click(function(){
$(this).toggleClass('active').next().slideToggle('slow');
return false;
});
$('#ouvrir').click(function() {
$contenu.show('slow');
return false;
});
$('#fermer').click(function() {
$contenu.hide('slow');
return false;
});
});
</script>
<script type="text/javascript">/*! jQuery v1.8.3 jquery.com | jquery.org/license */
(function(e,t){function _(e){var t=M[e]={};
return v.each(e.split(y),function(e,n){t[n]=!0}),t}function H(e,n,r){if(r===t&&e.nodeType===1){var i="data-"+n.replace(P,"-$1").toLowerCase();r=e.getAttribute(i);if(typeof r=="string"){try{r=r==="true"?!0:r==="false"?!1:r==="null"?null:+r+""===r?+r:D.test(r)?v.parseJSON(r):r}catch(s){}v.data(e,n,r)}else r=t}return r}function B(e){var t;for(t in e){if(t==="data"&&v.isEmptyObject(e[t]))continue;if(t!=="toJSON")return!1}return!0}function et(){return!1}function tt(){return!0}function ut(e){return!e||!e.parentNode||e.parentNode.nodeType===11}function at(e,t){do e=e[t];while(e&&e.nodeType!==1);return e}function ft(e,t,n){t=t||0;if(v.isFunction(t))return v.grep(e,function(e,r){var i=!!t.call(e,r,e);return i===n});if(t.nodeType)return v.grep(e,function(e,r){return e===t===n});if(typeof t=="string"){var r=v.grep(e,function(e){return e.nodeType===1});if(it.test(t))return v.filter(t,r,!n);t=v.filter(t,r)}return v.grep(e,function(e,r){return v.inArray(e,t)>=0===n})}function lt(e){var t=ct.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}function Lt(e,t){return e.getElementsByTagName(t)[0]||e.appendChild(e.ownerDocument.createElement(t))}function At(e,t){if(t.nodeType!==1||!v.hasData(e))return;var n,r,i,s=v._data(e),o=v._data(t,s),u=s.events;if(u){delete o.handle,o.events={};for(n in u)for(r=0,i=u[n].length;r<i;r++)v.event.add(t,n,u[n][r])}o.data&&(o.data=v.extend({},o.data))}function Ot(e,t){var n;if(t.nodeType!==1)return;t.clearAttributes&&t.clearAttributes(),t.mergeAttributes&&t.mergeAttributes(e),n=t.nodeName.toLowerCase(),n==="object"?(t.parentNode&&(t.outerHTML=e.outerHTML),v.support.html5Clone&&e.innerHTML&&!v.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):n==="input"&&Et.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):n==="option"?t.selected=e.defaultSelected:n==="input"||n==="textarea"?t.defaultValue=e.defaultValue:n==="script"&&t.text!==e.text&&(t.text=e.text),t.removeAttribute(v.expando)}function Mt(e){return typeof e.getElementsByTagName!="undefined"?e.getElementsByTagName("*"):typeof e.querySelectorAll!="undefined"?e.querySelectorAll("*"):[]}function _t(e){Et.test(e.type)&&(e.defaultChecked=e.checked)}function Qt(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=Jt.length;while(i--){t=Jt[i]+n;if(t in e)return t}return r}function Gt(e,t){return e=t||e,v.css(e,"display")==="none"||!v.contains(e.ownerDocument,e)}function Yt(e,t){var n,r,i=[],s=0,o=e.length;for(;s<o;s++){n=e[s];if(!n.style)continue;i[s]=v._data(n,"olddisplay"),t?(!i[s]&&n.style.display==="none"&&(n.style.display=""),n.style.display===""&&Gt(n)&&(i[s]=v._data(n,"olddisplay",nn(n.nodeName)))):(r=Dt(n,"display"),!i[s]&&r!=="none"&&v._data(n,"olddisplay",r))}for(s=0;s<o;s++){n=e[s];if(!n.style)continue;if(!t||n.style.display==="none"||n.style.display==="")n.style.display=t?i[s]||"":"none"}return e}function Zt(e,t,n){var r=Rt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function en(e,t,n,r){var i=n===(r?"border":"content")?4:t==="width"?1:0,s=0;for(;i<4;i+=2)n==="margin"&&(s+=v.css(e,n+$t[i],!0)),r?(n==="content"&&(s-=parseFloat(Dt(e,"padding"+$t[i]))||0),n!=="margin"&&(s-=parseFloat(Dt(e,"border"+$t[i]+"Width"))||0)):(s+=parseFloat(Dt(e,"padding"+$t[i]))||0,n!=="padding"&&(s+=parseFloat(Dt(e,"border"+$t[i]+"Width"))||0));return s}function tn(e,t,n){var r=t==="width"?e.offsetWidth:e.offsetHeight,i=!0,s=v.support.boxSizing&&v.css(e,"boxSizing")==="border-box";if(r<=0||r==null){r=Dt(e,t);if(r<0||r==null)r=e.style[t];if(Ut.test(r))return r;i=s&&(v.support.boxSizingReliable||r===e.style[t]),r=parseFloat(r)||0}return r+en(e,t,n||(s?"border":"content"),i)+"px"}function nn(e){if(Wt[e])return Wt[e];var t=v("<"+e+">").appendTo(i.body),n=t.css("display");t.remove();if(n==="none"||n===""){Pt=i.body.appendChild(Pt||v.extend(i.createElement("iframe"),{frameBorder:0,width:0,height:0}));if(!Ht||!Pt.createElement)Ht=(Pt.contentWindow||Pt.contentDocument).document,Ht.write("<!doctype html><html><body>"),Ht.close();t=Ht.body.appendChild(Ht.createElement(e)),n=Dt(t,"display"),i.body.removeChild(Pt)}return Wt[e]=n,n}function fn(e,t,n,r){var i;if(v.isArray(t))v.each(t,function(t,i){n||sn.test(e)?r(e,i):fn(e+"["+(typeof i=="object"?t:"")+"]",i,n,r)});else if(!n&&v.type(t)==="object")for(i in t)fn(e+"["+i+"]",t[i],n,r);else r(e,t)}function Cn(e){return function(t,n){typeof t!="string"&&(n=t,t="*");var r,i,s,o=t.toLowerCase().split(y),u=0,a=o.length;if(v.isFunction(n))for(;u<a;u++)r=o[u],s=/^\+/.test(r),s&&(r=r.substr(1)||"*"),i=e[r]=e[r]||[],i[s?"unshift":"push"](n)}}function kn(e,n,r,i,s,o){s=s||n.dataTypes[0],o=o||{},o[s]=!0;var u,a=e[s],f=0,l=a?a.length:0,c=e===Sn;for(;f<l&&(c||!u);f++)u=a[f](n,r,i),typeof u=="string"&&(!c||o[u]?u=t:(n.dataTypes.unshift(u),u=kn(e,n,r,i,u,o)));return(c||!u)&&!o["*"]&&(u=kn(e,n,r,i,"*",o)),u}function Ln(e,n){var r,i,s=v.ajaxSettings.flatOptions||{};for(r in n)n[r]!==t&&((s[r]?e:i||(i={}))[r]=n[r]);i&&v.extend(!0,e,i)}function An(e,n,r){var i,s,o,u,a=e.contents,f=e.dataTypes,l=e.responseFields;for(s in l)s in r&&(n[l[s]]=r[s]);while(f[0]==="*")f.shift(),i===t&&(i=e.mimeType||n.getResponseHeader("content-type"));if(i)for(s in a)if(a[s]&&a[s].test(i)){f.unshift(s);break}if(f[0]in r)o=f[0];else{for(s in r){if(!f[0]||e.converters[s+" "+f[0]]){o=s;break}u||(u=s)}o=o||u}if(o)return o!==f[0]&&f.unshift(o),r[o]}function On(e,t){var n,r,i,s,o=e.dataTypes.slice(),u=o[0],a={},f=0;e.dataFilter&&(t=e.dataFilter(t,e.dataType));if(o[1])for(n in e.converters)a[n.toLowerCase()]=e.converters[n];for(;i=o[++f];)if(i!=="*"){if(u!=="*"&&u!==i){n=a[u+" "+i]||a["* "+i];if(!n)for(r in a){s=r.split(" ");if(s[1]===i){n=a[u+" "+s[0]]||a["* "+s[0]];if(n){n===!0?n=a[r]:a[r]!==!0&&(i=s[0],o.splice(f--,0,i));break}}}if(n!==!0)if(n&&e["throws"])t=n(t);else try{t=n(t)}catch(l){return{state:"parsererror",error:n?l:"No conversion from "+u+" to "+i}}}u=i}return{state:"success",data:t}}function Fn(){try{return new e.XMLHttpRequest}catch(t){}}function In(){try{return new e.ActiveXObject("Microsoft.XMLHTTP")}catch(t){}}function $n(){return setTimeout(function(){qn=t},0),qn=v.now()}function Jn(e,t){v.each(t,function(t,n){var r=(Vn[t]||[]).concat(Vn["*"]),i=0,s=r.length;for(;i<s;i++)if(r[i].call(e,t,n))return})}function Kn(e,t,n){var r,i=0,s=0,o=Xn.length,u=v.Deferred().always(function(){delete a.elem}),a=function(){var t=qn||$n(),n=Math.max(0,f.startTime+f.duration-t),r=n/f.duration||0,i=1-r,s=0,o=f.tweens.length;for(;s<o;s++)f.tweens[s].run(i);return u.notifyWith(e,[f,i,n]),i<1&&o?n:(u.resolveWith(e,[f]),!1)},f=u.promise({elem:e,props:v.extend({},t),opts:v.extend(!0,{specialEasing:{}},n),originalProperties:t,originalOptions:n,startTime:qn||$n(),duration:n.duration,tweens:[],createTween:function(t,n,r){var i=v.Tween(e,f.opts,t,n,f.opts.specialEasing[t]||f.opts.easing);return f.tweens.push(i),i},stop:function(t){var n=0,r=t?f.tweens.length:0;for(;n<r;n++)f.tweens[n].run(1);return t?u.resolveWith(e,[f,t]):u.rejectWith(e,[f,t]),this}}),l=f.props;Qn(l,f.opts.specialEasing);for(;i<o;i++){r=Xn[i].call(f,e,l,f.opts);if(r)return r}return Jn(f,l),v.isFunction(f.opts.start)&&f.opts.start.call(e,f),v.fx.timer(v.extend(a,{anim:f,queue:f.opts.queue,elem:e})),f.progress(f.opts.progress).done(f.opts.done,f.opts.complete).fail(f.opts.fail).always(f.opts.always)}function Qn(e,t){var n,r,i,s,o;for(n in e){r=v.camelCase(n),i=t[r],s=e[n],v.isArray(s)&&(i=s[1],s=e[n]=s[0]),n!==r&&(e[r]=s,delete e[n]),o=v.cssHooks[r];if(o&&"expand"in o){s=o.expand(s),delete e[r];for(n in s)n in e||(e[n]=s[n],t[n]=i)}else t[r]=i}}function Gn(e,t,n){var r,i,s,o,u,a,f,l,c,h=this,p=e.style,d={},m=[],g=e.nodeType&&Gt(e);n.queue||(l=v._queueHooks(e,"fx"),l.unqueued==null&&(l.unqueued=0,c=l.empty.fire,l.empty.fire=function(){l.unqueued||c()}),l.unqueued++,h.always(function(){h.always(function(){l.unqueued--,v.queue(e,"fx").length||l.empty.fire()})})),e.nodeType===1&&("height"in t||"width"in t)&&(n.overflow=[p.overflow,p.overflowX,p.overflowY],v.css(e,"display")==="inline"&&v.css(e,"float")==="none"&&(!v.support.inlineBlockNeedsLayout||nn(e.nodeName)==="inline"?p.display="inline-block":p.zoom=1)),n.overflow&&(p.overflow="hidden",v.support.shrinkWrapBlocks||h.done(function(){p.overflow=n.overflow[0],p.overflowX=n.overflow[1],p.overflowY=n.overflow[2]}));for(r in t){s=t[r];if(Un.exec(s)){delete t[r],a=a||s==="toggle";if(s===(g?"hide":"show"))continue;m.push(r)}}o=m.length;if(o){u=v._data(e,"fxshow")||v._data(e,"fxshow",{}),"hidden"in u&&(g=u.hidden),a&&(u.hidden=!g),g?v(e).show():h.done(function(){v(e).hide()}),h.done(function(){var t;v.removeData(e,"fxshow",!0);for(t in d)v.style(e,t,d[t])});for(r=0;r<o;r++)i=m[r],f=h.createTween(i,g?u[i]:0),d[i]=u[i]||v.style(e,i),i in u||(u[i]=f.start,g&&(f.end=f.start,f.start=i==="width"||i==="height"?1:0))}}function Yn(e,t,n,r,i){return new Yn.prototype.init(e,t,n,r,i)}function Zn(e,t){var n,r={height:e},i=0;t=t?1:0;for(;i<4;i+=2-t)n=$t[i],r["margin"+n]=r["padding"+n]=e;return t&&(r.opacity=r.width=e),r}function tr(e){return v.isWindow(e)?e:e.nodeType===9?e.defaultView||e.parentWindow:!1}var n,r,i=e.document,s=e.location,o=e.navigator,u=e.jQuery,a=e.$,f=Array.prototype.push,l=Array.prototype.slice,c=Array.prototype.indexOf,h=Object.prototype.toString,p=Object.prototype.hasOwnProperty,d=String.prototype.trim,v=function(e,t){return new v.fn.init(e,t,n)},m=/[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source,g=/\S/,y=/\s+/,b=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,w=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,E=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,S=/^[\],:{}\s]*$/,x=/(?:^|:|,)(?:\s*\[)+/g,T=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,N=/"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,C=/^-ms-/,k=/-([\da-z])/gi,L=function(e,t){return(t+"").toUpperCase()},A=function(){i.addEventListener?(i.removeEventListener("DOMContentLoaded",A,!1),v.ready()):i.readyState==="complete"&&(i.detachEvent("onreadystatechange",A),v.ready())},O={};v.fn=v.prototype={constructor:v,init:function(e,n,r){var s,o,u,a;if(!e)return this;if(e.nodeType)return this.context=this[0]=e,this.length=1,this;if(typeof e=="string"){e.charAt(0)==="<"&&e.charAt(e.length-1)===">"&&e.length>=3?s=[null,e,null]:s=w.exec(e);if(s&&(s[1]||!n)){if(s[1])return n=n instanceof v?n[0]:n,a=n&&n.nodeType?n.ownerDocument||n:i,e=v.parseHTML(s[1],a,!0),E.test(s[1])&&v.isPlainObject(n)&&this.attr.call(e,n,!0),v.merge(this,e);o=i.getElementById(s[2]);if(o&&o.parentNode){if(o.id!==s[2])return r.find(e);this.length=1,this[0]=o}return this.context=i,this.selector=e,this}return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e)}return v.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),v.makeArray(e,this))},selector:"",jquery:"1.8.3",length:0,size:function(){return this.length},toArray:function(){return l.call(this)},get:function(e){return e==null?this.toArray():e<0?this[this.length+e]:this[e]},pushStack:function(e,t,n){var r=v.merge(this.constructor(),e);return r.prevObject=this,r.context=this.context,t==="find"?r.selector=this.selector+(this.selector?" ":"")+n:t&&(r.selector=this.selector+"."+t+"("+n+")"),r},each:function(e,t){return v.each(this,e,t)},ready:function(e){return v.ready.promise().done(e),this},eq:function(e){return e=+e,e===-1?this.slice(e):this.slice(e,e+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(l.apply(this,arguments),"slice",l.call(arguments).join(","))},map:function(e){return this.pushStack(v.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:[].sort,splice:[].splice},v.fn.init.prototype=v.fn,v.extend=v.fn.extend=function(){var e,n,r,i,s,o,u=arguments[0]||{},a=1,f=arguments.length,l=!1;typeof u=="boolean"&&(l=u,u=arguments[1]||{},a=2),typeof u!="object"&&!v.isFunction(u)&&(u={}),f===a&&(u=this,--a);for(;a<f;a++)if((e=arguments[a])!=null)for(n in e){r=u[n],i=e[n];if(u===i)continue;l&&i&&(v.isPlainObject(i)||(s=v.isArray(i)))?(s?(s=!1,o=r&&v.isArray(r)?r:[]):o=r&&v.isPlainObject(r)?r:{},u[n]=v.extend(l,o,i)):i!==t&&(u[n]=i)}return u},v.extend({noConflict:function(t){return e.$===v&&(e.$=a),t&&e.jQuery===v&&(e.jQuery=u),v},isReady:!1,readyWait:1,holdReady:function(e){e?v.readyWait++:v.ready(!0)},ready:function(e){if(e===!0?--v.readyWait:v.isReady)return;if(!i.body)return setTimeout(v.ready,1);v.isReady=!0;if(e!==!0&&--v.readyWait>0)return;r.resolveWith(i,[v]),v.fn.trigger&&v(i).trigger("ready").off("ready")},isFunction:function(e){return v.type(e)==="function"},isArray:Array.isArray||function(e){return v.type(e)==="array"},isWindow:function(e){return e!=null&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return e==null?String(e):O[h.call(e)]||"object"},isPlainObject:function(e){if(!e||v.type(e)!=="object"||e.nodeType||v.isWindow(e))return!1;try{if(e.constructor&&!p.call(e,"constructor")&&!p.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(n){return!1}var r;for(r in e);return r===t||p.call(e,r)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw new Error(e)},parseHTML:function(e,t,n){var r;return!e||typeof e!="string"?null:(typeof t=="boolean"&&(n=t,t=0),t=t||i,(r=E.exec(e))?[t.createElement(r[1])]:(r=v.buildFragment([e],t,n?null:[]),v.merge([],(r.cacheable?v.clone(r.fragment):r.fragment).childNodes)))},parseJSON:function(t){if(!t||typeof t!="string")return null;t=v.trim(t);if(e.JSON&&e.JSON.parse)return e.JSON.parse(t);if(S.test(t.replace(T,"@").replace(N,"]").replace(x,"")))return(new Function("return "+t))();v.error("Invalid JSON: "+t)},parseXML:function(n){var r,i;if(!n||typeof n!="string")return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(s){r=t}return(!r||!r.documentElement||r.getElementsByTagName("parsererror").length)&&v.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&g.test(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(C,"ms-").replace(k,L)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,n,r){var i,s=0,o=e.length,u=o===t||v.isFunction(e);if(r){if(u){for(i in e)if(n.apply(e[i],r)===!1)break}else for(;s<o;)if(n.apply(e[s++],r)===!1)break}else if(u){for(i in e)if(n.call(e[i],i,e[i])===!1)break}else for(;s<o;)if(n.call(e[s],s,e[s++])===!1)break;return e},trim:d&&!d.call("\ufeff\u00a0")?function(e){return e==null?"":d.call(e)}:function(e){return e==null?"":(e+"").replace(b,"")},makeArray:function(e,t){var n,r=t||[];return e!=null&&(n=v.type(e),e.length==null||n==="string"||n==="function"||n==="regexp"||v.isWindow(e)?f.call(r,e):v.merge(r,e)),r},inArray:function(e,t,n){var r;if(t){if(c)return c.call(t,e,n);r=t.length,n=n?n<0?Math.max(0,r+n):n:0;for(;n<r;n++)if(n in t&&t[n]===e)return n}return-1},merge:function(e,n){var r=n.length,i=e.length,s=0;if(typeof r=="number")for(;s<r;s++)e[i++]=n[s];else while(n[s]!==t)e[i++]=n[s++];return e.length=i,e},grep:function(e,t,n){var r,i=[],s=0,o=e.length;n=!!n;for(;s<o;s++)r=!!t(e[s],s),n!==r&&i.push(e[s]);return i},map:function(e,n,r){var i,s,o=[],u=0,a=e.length,f=e instanceof v||a!==t&&typeof a=="number"&&(a>0&&e[0]&&e[a-1]||a===0||v.isArray(e));if(f)for(;u<a;u++)i=n(e[u],u,r),i!=null&&(o[o.length]=i);else for(s in e)i=n(e[s],s,r),i!=null&&(o[o.length]=i);return o.concat.apply([],o)},guid:1,proxy:function(e,n){var r,i,s;return typeof n=="string"&&(r=e[n],n=e,e=r),v.isFunction(e)?(i=l.call(arguments,2),s=function(){return e.apply(n,i.concat(l.call(arguments)))},s.guid=e.guid=e.guid||v.guid++,s):t},access:function(e,n,r,i,s,o,u){var a,f=r==null,l=0,c=e.length;if(r&&typeof r=="object"){for(l in r)v.access(e,n,l,r[l],1,o,i);s=1}else if(i!==t){a=u===t&&v.isFunction(i),f&&(a?(a=n,n=function(e,t,n){return a.call(v(e),n)}):(n.call(e,i),n=null));if(n)for(;l<c;l++)n(e[l],r,a?i.call(e[l],l,n(e[l],r)):i,u);s=1}return s?e:f?n.call(e):c?n(e[0],r):o},now:function(){return(new Date).getTime()}}),v.ready.promise=function(t){if(!r){r=v.Deferred();if(i.readyState==="complete")setTimeout(v.ready,1);else if(i.addEventListener)i.addEventListener("DOMContentLoaded",A,!1),e.addEventListener("load",v.ready,!1);else{i.attachEvent("onreadystatechange",A),e.attachEvent("onload",v.ready);var n=!1;try{n=e.frameElement==null&&i.documentElement}catch(s){}n&&n.doScroll&&function o(){if(!v.isReady){try{n.doScroll("left")}catch(e){return setTimeout(o,50)}v.ready()}}()}}return r.promise(t)},v.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(e,t){O["[object "+t+"]"]=t.toLowerCase()}),n=v(i);var M={};v.Callbacks=function(e){e=typeof e=="string"?M[e]||_(e):v.extend({},e);var n,r,i,s,o,u,a=[],f=!e.once&&[],l=function(t){n=e.memory&&t,r=!0,u=s||0,s=0,o=a.length,i=!0;for(;a&&u<o;u++)if(a[u].apply(t[0],t[1])===!1&&e.stopOnFalse){n=!1;break}i=!1,a&&(f?f.length&&l(f.shift()):n?a=[]:c.disable())},c={add:function(){if(a){var t=a.length;(function r(t){v.each(t,function(t,n){var i=v.type(n);i==="function"?(!e.unique||!c.has(n))&&a.push(n):n&&n.length&&i!=="string"&&r(n)})})(arguments),i?o=a.length:n&&(s=t,l(n))}return this},remove:function(){return a&&v.each(arguments,function(e,t){var n;while((n=v.inArray(t,a,n))>-1)a.splice(n,1),i&&(n<=o&&o--,n<=u&&u--)}),this},has:function(e){return v.inArray(e,a)>-1},empty:function(){return a=[],this},disable:function(){return a=f=n=t,this},disabled:function(){return!a},lock:function(){return f=t,n||c.disable(),this},locked:function(){return!f},fireWith:function(e,t){return t=t||[],t=[e,t.slice?t.slice():t],a&&(!r||f)&&(i?f.push(t):l(t)),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!r}};return c},v.extend({Deferred:function(e){var t=[["resolve","done",v.Callbacks("once memory"),"resolved"],["reject","fail",v.Callbacks("once memory"),"rejected"],["notify","progress",v.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return v.Deferred(function(n){v.each(t,function(t,r){var s=r[0],o=e[t];i[r[1]](v.isFunction(o)?function(){var e=o.apply(this,arguments);e&&v.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[s+"With"](this===i?n:this,[e])}:n[s])}),e=null}).promise()},promise:function(e){return e!=null?v.extend(e,r):r}},i={};return r.pipe=r.then,v.each(t,function(e,s){var o=s[2],u=s[3];r[s[1]]=o.add,u&&o.add(function(){n=u},t[e^1][2].disable,t[2][2].lock),i[s[0]]=o.fire,i[s[0]+"With"]=o.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=l.call(arguments),r=n.length,i=r!==1||e&&v.isFunction(e.promise)?r:0,s=i===1?e:v.Deferred(),o=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?l.call(arguments):r,n===u?s.notifyWith(t,n):--i||s.resolveWith(t,n)}},u,a,f;if(r>1){u=new Array(r),a=new Array(r),f=new Array(r);for(;t<r;t++)n[t]&&v.isFunction(n[t].promise)?n[t].promise().done(o(t,f,n)).fail(s.reject).progress(o(t,a,u)):--i}return i||s.resolveWith(f,n),s.promise()}}),v.support=function(){var t,n,r,s,o,u,a,f,l,c,h,p=i.createElement("div");p.setAttribute("className","t"),p.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",n=p.getElementsByTagName("*"),r=p.getElementsByTagName("a")[0];if(!n||!r||!n.length)return{};s=i.createElement("select"),o=s.appendChild(i.createElement("option")),u=p.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t={leadingWhitespace:p.firstChild.nodeType===3,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.getElementsByTagName("link").length,style:/top/.test(r.getAttribute("style")),hrefNormalized:r.getAttribute("href")==="/a",opacity:/^0.5/.test(r.style.opacity),cssFloat:!!r.style.cssFloat,checkOn:u.value==="on",optSelected:o.selected,getSetAttribute:p.className!=="t",enctype:!!i.createElement("form").enctype,html5Clone:i.createElement("nav").cloneNode(!0).outerHTML!=="<:nav></:nav>",boxModel:i.compatMode==="CSS1Compat",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},u.checked=!0,t.noCloneChecked=u.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!o.disabled;try{delete p.test}catch(d){t.deleteExpando=!1}!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent("onclick",h=function(){t.noCloneEvent=!1}),p.cloneNode(!0).fireEvent("onclick"),p.detachEvent("onclick",h)),u=i.createElement("input"),u.value="t",u.setAttribute("type","radio"),t.radioValue=u.value==="t",u.setAttribute("checked","checked"),u.setAttribute("name","t"),p.appendChild(u),a=i.createDocumentFragment(),a.appendChild(p.lastChild),t.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,t.appendChecked=u.checked,a.removeChild(u),a.appendChild(p);if(p.attachEvent)for(l in{submit:!0,change:!0,focusin:!0})f="on"+l,c=f in p,c||(p.setAttribute(f,"return;"),c=typeof p[f]=="function"),t[l+"Bubbles"]=c;return v(function(){var n,r,s,o,u="padding:0;margin:0;border:0;display:block;overflow:hidden;",a=i.getElementsByTagName("body")[0];if(!a)return;n=i.createElement("div"),n.style.cssText="visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px",a.insertBefore(n,a.firstChild),r=i.createElement("div"),n.appendChild(r),r.innerHTML="<table><tr><td></td><td>t</td></tr></table>",s=r.getElementsByTagName("td"),s[0].style.cssText="padding:0;margin:0;border:0;display:none",c=s[0].offsetHeight===0,s[0].style.display="",s[1].style.display="none",t.reliableHiddenOffsets=c&&s[0].offsetHeight===0,r.innerHTML="",r.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",t.boxSizing=r.offsetWidth===4,t.doesNotIncludeMarginInBodyOffset=a.offsetTop!==1,e.getComputedStyle&&(t.pixelPosition=(e.getComputedStyle(r,null)||{}).top!=="1%",t.boxSizingReliable=(e.getComputedStyle(r,null)||{width:"4px"}).width==="4px",o=i.createElement("div"),o.style.cssText=r.style.cssText=u,o.style.marginRight=o.style.width="0",r.style.width="1px",r.appendChild(o),t.reliableMarginRight=!parseFloat((e.getComputedStyle(o,null)||{}).marginRight)),typeof r.style.zoom!="undefined"&&(r.innerHTML="",r.style.cssText=u+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=r.offsetWidth===3,r.style.display="block",r.style.overflow="visible",r.innerHTML="<div></div>",r.firstChild.style.width="5px",t.shrinkWrapBlocks=r.offsetWidth!==3,n.style.zoom=1),a.removeChild(n),n=r=s=o=null}),a.removeChild(p),n=r=s=o=u=a=p=null,t}();var D=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,P=/([A-Z])/g;v.extend({cache:{},deletedIds:[],uuid:0,expando:"jQuery"+(v.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(e){return e=e.nodeType?v.cache[e[v.expando]]:e[v.expando],!!e&&!B(e)},data:function(e,n,r,i){if(!v.acceptData(e))return;var s,o,u=v.expando,a=typeof n=="string",f=e.nodeType,l=f?v.cache:e,c=f?e[u]:e[u]&&u;if((!c||!l[c]||!i&&!l[c].data)&&a&&r===t)return;c||(f?e[u]=c=v.deletedIds.pop()||v.guid++:c=u),l[c]||(l[c]={},f||(l[c].toJSON=v.noop));if(typeof n=="object"||typeof n=="function")i?l[c]=v.extend(l[c],n):l[c].data=v.extend(l[c].data,n);return s=l[c],i||(s.data||(s.data={}),s=s.data),r!==t&&(s[v.camelCase(n)]=r),a?(o=s[n],o==null&&(o=s[v.camelCase(n)])):o=s,o},removeData:function(e,t,n){if(!v.acceptData(e))return;var r,i,s,o=e.nodeType,u=o?v.cache:e,a=o?e[v.expando]:v.expando;if(!u[a])return;if(t){r=n?u[a]:u[a].data;if(r){v.isArray(t)||(t in r?t=[t]:(t=v.camelCase(t),t in r?t=[t]:t=t.split(" ")));for(i=0,s=t.length;i<s;i++)delete r[t[i]];if(!(n?B:v.isEmptyObject)(r))return}}if(!n){delete u[a].data;if(!B(u[a]))return}o?v.cleanData([e],!0):v.support.deleteExpando||u!=u.window?delete u[a]:u[a]=null},_data:function(e,t,n){return v.data(e,t,n,!0)},acceptData:function(e){var t=e.nodeName&&v.noData[e.nodeName.toLowerCase()];return!t||t!==!0&&e.getAttribute("classid")===t}}),v.fn.extend({data:function(e,n){var r,i,s,o,u,a=this[0],f=0,l=null;if(e===t){if(this.length){l=v.data(a);if(a.nodeType===1&&!v._data(a,"parsedAttrs")){s=a.attributes;for(u=s.length;f<u;f++)o=s[f].name,o.indexOf("data-")||(o=v.camelCase(o.substring(5)),H(a,o,l[o]));v._data(a,"parsedAttrs",!0)}}return l}return typeof e=="object"?this.each(function(){v.data(this,e)}):(r=e.split(".",2),r[1]=r[1]?"."+r[1]:"",i=r[1]+"!",v.access(this,function(n){if(n===t)return l=this.triggerHandler("getData"+i,[r[0]]),l===t&&a&&(l=v.data(a,e),l=H(a,e,l)),l===t&&r[1]?this.data(r[0]):l;r[1]=n,this.each(function(){var t=v(this);t.triggerHandler("setData"+i,r),v.data(this,e,n),t.triggerHandler("changeData"+i,r)})},null,n,arguments.length>1,null,!1))},removeData:function(e){return this.each(function(){v.removeData(this,e)})}}),v.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=v._data(e,t),n&&(!r||v.isArray(n)?r=v._data(e,t,v.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=v.queue(e,t),r=n.length,i=n.shift(),s=v._queueHooks(e,t),o=function(){v.dequeue(e,t)};i==="inprogress"&&(i=n.shift(),r--),i&&(t==="fx"&&n.unshift("inprogress"),delete s.stop,i.call(e,o,s)),!r&&s&&s.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return v._data(e,n)||v._data(e,n,{empty:v.Callbacks("once memory").add(function(){v.removeData(e,t+"queue",!0),v.removeData(e,n,!0)})})}}),v.fn.extend({queue:function(e,n){var r=2;return typeof e!="string"&&(n=e,e="fx",r--),arguments.length<r?v.queue(this[0],e):n===t?this:this.each(function(){var t=v.queue(this,e,n);v._queueHooks(this,e),e==="fx"&&t[0]!=="inprogress"&&v.dequeue(this,e)})},dequeue:function(e){return this.each(function(){v.dequeue(this,e)})},delay:function(e,t){return e=v.fx?v.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,n){var r,i=1,s=v.Deferred(),o=this,u=this.length,a=function(){--i||s.resolveWith(o,[o])};typeof e!="string"&&(n=e,e=t),e=e||"fx";while(u--)r=v._data(o[u],e+"queueHooks"),r&&r.empty&&(i++,r.empty.add(a));return a(),s.promise(n)}});var j,F,I,q=/[\t\r\n]/g,R=/\r/g,U=/^(?:button|input)$/i,z=/^(?:button|input|object|select|textarea)$/i,W=/^a(?:rea|)$/i,X=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,V=v.support.getSetAttribute;v.fn.extend({attr:function(e,t){return v.access(this,v.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){v.removeAttr(this,e)})},prop:function(e,t){return v.access(this,v.prop,e,t,arguments.length>1)},removeProp:function(e){return e=v.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,s,o,u;if(v.isFunction(e))return this.each(function(t){v(this).addClass(e.call(this,t,this.className))});if(e&&typeof e=="string"){t=e.split(y);for(n=0,r=this.length;n<r;n++){i=this[n];if(i.nodeType===1)if(!i.className&&t.length===1)i.className=e;else{s=" "+i.className+" ";for(o=0,u=t.length;o<u;o++)s.indexOf(" "+t[o]+" ")<0&&(s+=t[o]+" ");i.className=v.trim(s)}}}return this},removeClass:function(e){var n,r,i,s,o,u,a;if(v.isFunction(e))return this.each(function(t){v(this).removeClass(e.call(this,t,this.className))});if(e&&typeof e=="string"||e===t){n=(e||"").split(y);for(u=0,a=this.length;u<a;u++){i=this[u];if(i.nodeType===1&&i.className){r=(" "+i.className+" ").replace(q," ");for(s=0,o=n.length;s<o;s++)while(r.indexOf(" "+n[s]+" ")>=0)r=r.replace(" "+n[s]+" "," ");i.className=e?v.trim(r):""}}}return this},toggleClass:function(e,t){var n=typeof e,r=typeof t=="boolean";return v.isFunction(e)?this.each(function(n){v(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if(n==="string"){var i,s=0,o=v(this),u=t,a=e.split(y);while(i=a[s++])u=r?u:!o.hasClass(i),o[u?"addClass":"removeClass"](i)}else if(n==="undefined"||n==="boolean")this.className&&v._data(this,"__className__",this.className),this.className=this.className||e===!1?"":v._data(this,"__className__")||""})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;n<r;n++)if(this[n].nodeType===1&&(" "+this[n].className+" ").replace(q," ").indexOf(t)>=0)return!0;return!1},val:function(e){var n,r,i,s=this[0];if(!arguments.length){if(s)return n=v.valHooks[s.type]||v.valHooks[s.nodeName.toLowerCase()],n&&"get"in n&&(r=n.get(s,"value"))!==t?r:(r=s.value,typeof r=="string"?r.replace(R,""):r==null?"":r);return}return i=v.isFunction(e),this.each(function(r){var s,o=v(this);if(this.nodeType!==1)return;i?s=e.call(this,r,o.val()):s=e,s==null?s="":typeof s=="number"?s+="":v.isArray(s)&&(s=v.map(s,function(e){return e==null?"":e+""})),n=v.valHooks[this.type]||v.valHooks[this.nodeName.toLowerCase()];if(!n||!("set"in n)||n.set(this,s,"value")===t)this.value=s})}}),v.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,s=e.type==="select-one"||i<0,o=s?null:[],u=s?i+1:r.length,a=i<0?u:s?i:0;for(;a<u;a++){n=r[a];if((n.selected||a===i)&&(v.support.optDisabled?!n.disabled:n.getAttribute("disabled")===null)&&(!n.parentNode.disabled||!v.nodeName(n.parentNode,"optgroup"))){t=v(n).val();if(s)return t;o.push(t)}}return o},set:function(e,t){var n=v.makeArray(t);return v(e).find("option").each(function(){this.selected=v.inArray(v(this).val(),n)>=0}),n.length||(e.selectedIndex=-1),n}}},attrFn:{},attr:function(e,n,r,i){var s,o,u,a=e.nodeType;if(!e||a===3||a===8||a===2)return;if(i&&v.isFunction(v.fn[n]))return v(e)[n](r);if(typeof e.getAttribute=="undefined")return v.prop(e,n,r);u=a!==1||!v.isXMLDoc(e),u&&(n=n.toLowerCase(),o=v.attrHooks[n]||(X.test(n)?F:j));if(r!==t){if(r===null){v.removeAttr(e,n);return}return o&&"set"in o&&u&&(s=o.set(e,r,n))!==t?s:(e.setAttribute(n,r+""),r)}return o&&"get"in o&&u&&(s=o.get(e,n))!==null?s:(s=e.getAttribute(n),s===null?t:s)},removeAttr:function(e,t){var n,r,i,s,o=0;if(t&&e.nodeType===1){r=t.split(y);for(;o<r.length;o++)i=r[o],i&&(n=v.propFix[i]||i,s=X.test(i),s||v.attr(e,i,""),e.removeAttribute(V?i:n),s&&n in e&&(e[n]=!1))}},attrHooks:{type:{set:function(e,t){if(U.test(e.nodeName)&&e.parentNode)v.error("type property can't be changed");else if(!v.support.radioValue&&t==="radio"&&v.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}},value:{get:function(e,t){return j&&v.nodeName(e,"button")?j.get(e,t):t in e?e.value:null},set:function(e,t,n){if(j&&v.nodeName(e,"button"))return j.set(e,t,n);e.value=t}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(e,n,r){var i,s,o,u=e.nodeType;if(!e||u===3||u===8||u===2)return;return o=u!==1||!v.isXMLDoc(e),o&&(n=v.propFix[n]||n,s=v.propHooks[n]),r!==t?s&&"set"in s&&(i=s.set(e,r,n))!==t?i:e[n]=r:s&&"get"in s&&(i=s.get(e,n))!==null?i:e[n]},propHooks:{tabIndex:{get:function(e){var n=e.getAttributeNode("tabindex");return n&&n.specified?parseInt(n.value,10):z.test(e.nodeName)||W.test(e.nodeName)&&e.href?0:t}}}}),F={get:function(e,n){var r,i=v.prop(e,n);return i===!0||typeof i!="boolean"&&(r=e.getAttributeNode(n))&&r.nodeValue!==!1?n.toLowerCase():t},set:function(e,t,n){var r;return t===!1?v.removeAttr(e,n):(r=v.propFix[n]||n,r in e&&(e[r]=!0),e.setAttribute(n,n.toLowerCase())),n}},V||(I={name:!0,id:!0,coords:!0},j=v.valHooks.button={get:function(e,n){var r;return r=e.getAttributeNode(n),r&&(I[n]?r.value!=="":r.specified)?r.value:t},set:function(e,t,n){var r=e.getAttributeNode(n);return r||(r=i.createAttribute(n),e.setAttributeNode(r)),r.value=t+""}},v.each(["width","height"],function(e,t){v.attrHooks[t]=v.extend(v.attrHooks[t],{set:function(e,n){if(n==="")return e.setAttribute(t,"auto"),n}})}),v.attrHooks.contenteditable={get:j.get,set:function(e,t,n){t===""&&(t="false"),j.set(e,t,n)}}),v.support.hrefNormalized||v.each(["href","src","width","height"],function(e,n){v.attrHooks[n]=v.extend(v.attrHooks[n],{get:function(e){var r=e.getAttribute(n,2);return r===null?t:r}})}),v.support.style||(v.attrHooks.style={get:function(e){return e.style.cssText.toLowerCase()||t},set:function(e,t){return e.style.cssText=t+""}}),v.support.optSelected||(v.propHooks.selected=v.extend(v.propHooks.selected,{get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null}})),v.support.enctype||(v.propFix.enctype="encoding"),v.support.checkOn||v.each(["radio","checkbox"],function(){v.valHooks[this]={get:function(e){return e.getAttribute("value")===null?"on":e.value}}}),v.each(["radio","checkbox"],function(){v.valHooks[this]=v.extend(v.valHooks[this],{set:function(e,t){if(v.isArray(t))return e.checked=v.inArray(v(e).val(),t)>=0}})});var $=/^(?:textarea|input|select)$/i,J=/^([^\.]*|)(?:\.(.+)|)$/,K=/(?:^|\s)hover(\.\S+|)\b/,Q=/^key/,G=/^(?:mouse|contextmenu)|click/,Y=/^(?:focusinfocus|focusoutblur)$/,Z=function(e){return v.event.special.hover?e:e.replace(K,"mouseenter$1 mouseleave$1")};v.event={add:function(e,n,r,i,s){var o,u,a,f,l,c,h,p,d,m,g;if(e.nodeType===3||e.nodeType===8||!n||!r||!(o=v._data(e)))return;r.handler&&(d=r,r=d.handler,s=d.selector),r.guid||(r.guid=v.guid++),a=o.events,a||(o.events=a={}),u=o.handle,u||(o.handle=u=function(e){return typeof v=="undefined"||!!e&&v.event.triggered===e.type?t:v.event.dispatch.apply(u.elem,arguments)},u.elem=e),n=v.trim(Z(n)).split(" ");for(f=0;f<n.length;f++){l=J.exec(n[f])||[],c=l[1],h=(l[2]||"").split(".").sort(),g=v.event.special[c]||{},c=(s?g.delegateType:g.bindType)||c,g=v.event.special[c]||{},p=v.extend({type:c,origType:l[1],data:i,handler:r,guid:r.guid,selector:s,needsContext:s&&v.expr.match.needsContext.test(s),namespace:h.join(".")},d),m=a[c];if(!m){m=a[c]=[],m.delegateCount=0;if(!g.setup||g.setup.call(e,i,h,u)===!1)e.addEventListener?e.addEventListener(c,u,!1):e.attachEvent&&e.attachEvent("on"+c,u)}g.add&&(g.add.call(e,p),p.handler.guid||(p.handler.guid=r.guid)),s?m.splice(m.delegateCount++,0,p):m.push(p),v.event.global[c]=!0}e=null},global:{},remove:function(e,t,n,r,i){var s,o,u,a,f,l,c,h,p,d,m,g=v.hasData(e)&&v._data(e);if(!g||!(h=g.events))return;t=v.trim(Z(t||"")).split(" ");for(s=0;s<t.length;s++){o=J.exec(t[s])||[],u=a=o[1],f=o[2];if(!u){for(u in h)v.event.remove(e,u+t[s],n,r,!0);continue}p=v.event.special[u]||{},u=(r?p.delegateType:p.bindType)||u,d=h[u]||[],l=d.length,f=f?new RegExp("(^|\\.)"+f.split(".").sort().join("\\.(?:.*\\.|)")+"(\\.|$)"):null;for(c=0;c<d.length;c++)m=d[c],(i||a===m.origType)&&(!n||n.guid===m.guid)&&(!f||f.test(m.namespace))&&(!r||r===m.selector||r==="**"&&m.selector)&&(d.splice(c--,1),m.selector&&d.delegateCount--,p.remove&&p.remove.call(e,m));d.length===0&&l!==d.length&&((!p.teardown||p.teardown.call(e,f,g.handle)===!1)&&v.removeEvent(e,u,g.handle),delete h[u])}v.isEmptyObject(h)&&(delete g.handle,v.removeData(e,"events",!0))},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(n,r,s,o){if(!s||s.nodeType!==3&&s.nodeType!==8){var u,a,f,l,c,h,p,d,m,g,y=n.type||n,b=[];if(Y.test(y+v.event.triggered))return;y.indexOf("!")>=0&&(y=y.slice(0,-1),a=!0),y.indexOf(".")>=0&&(b=y.split("."),y=b.shift(),b.sort());if((!s||v.event.customEvent[y])&&!v.event.global[y])return;n=typeof n=="object"?n[v.expando]?n:new v.Event(y,n):new v.Event(y),n.type=y,n.isTrigger=!0,n.exclusive=a,n.namespace=b.join("."),n.namespace_re=n.namespace?new RegExp("(^|\\.)"+b.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,h=y.indexOf(":")<0?"on"+y:"";if(!s){u=v.cache;for(f in u)u[f].events&&u[f].events[y]&&v.event.trigger(n,r,u[f].handle.elem,!0);return}n.result=t,n.target||(n.target=s),r=r!=null?v.makeArray(r):[],r.unshift(n),p=v.event.special[y]||{};if(p.trigger&&p.trigger.apply(s,r)===!1)return;m=[[s,p.bindType||y]];if(!o&&!p.noBubble&&!v.isWindow(s)){g=p.delegateType||y,l=Y.test(g+y)?s:s.parentNode;for(c=s;l;l=l.parentNode)m.push([l,g]),c=l;c===(s.ownerDocument||i)&&m.push([c.defaultView||c.parentWindow||e,g])}for(f=0;f<m.length&&!n.isPropagationStopped();f++)l=m[f][0],n.type=m[f][1],d=(v._data(l,"events")||{})[n.type]&&v._data(l,"handle"),d&&d.apply(l,r),d=h&&l[h],d&&v.acceptData(l)&&d.apply&&d.apply(l,r)===!1&&n.preventDefault();return n.type=y,!o&&!n.isDefaultPrevented()&&(!p._default||p._default.apply(s.ownerDocument,r)===!1)&&(y!=="click"||!v.nodeName(s,"a"))&&v.acceptData(s)&&h&&s[y]&&(y!=="focus"&&y!=="blur"||n.target.offsetWidth!==0)&&!v.isWindow(s)&&(c=s[h],c&&(s[h]=null),v.event.triggered=y,s[y](),v.event.triggered=t,c&&(s[h]=c)),n.result}return},dispatch:function(n){n=v.event.fix(n||e.event);var r,i,s,o,u,a,f,c,h,p,d=(v._data(this,"events")||{})[n.type]||[],m=d.delegateCount,g=l.call(arguments),y=!n.exclusive&&!n.namespace,b=v.event.special[n.type]||{},w=[];g[0]=n,n.delegateTarget=this;if(b.preDispatch&&b.preDispatch.call(this,n)===!1)return;if(m&&(!n.button||n.type!=="click"))for(s=n.target;s!=this;s=s.parentNode||this)if(s.disabled!==!0||n.type!=="click"){u={},f=[];for(r=0;r<m;r++)c=d[r],h=c.selector,u[h]===t&&(u[h]=c.needsContext?v(h,this).index(s)>=0:v.find(h,this,null,[s]).length),u[h]&&f.push(c);f.length&&w.push({elem:s,matches:f})}d.length>m&&w.push({elem:this,matches:d.slice(m)});for(r=0;r<w.length&&!n.isPropagationStopped();r++){a=w[r],n.currentTarget=a.elem;for(i=0;i<a.matches.length&&!n.isImmediatePropagationStopped();i++){c=a.matches[i];if(y||!n.namespace&&!c.namespace||n.namespace_re&&n.namespace_re.test(c.namespace))n.data=c.data,n.handleObj=c,o=((v.event.special[c.origType]||{}).handle||c.handler).apply(a.elem,g),o!==t&&(n.result=o,o===!1&&(n.preventDefault(),n.stopPropagation()))}}return b.postDispatch&&b.postDispatch.call(this,n),n.result},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return e.which==null&&(e.which=t.charCode!=null?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,n){var r,s,o,u=n.button,a=n.fromElement;return e.pageX==null&&n.clientX!=null&&(r=e.target.ownerDocument||i,s=r.documentElement,o=r.body,e.pageX=n.clientX+(s&&s.scrollLeft||o&&o.scrollLeft||0)-(s&&s.clientLeft||o&&o.clientLeft||0),e.pageY=n.clientY+(s&&s.scrollTop||o&&o.scrollTop||0)-(s&&s.clientTop||o&&o.clientTop||0)),!e.relatedTarget&&a&&(e.relatedTarget=a===e.target?n.toElement:a),!e.which&&u!==t&&(e.which=u&1?1:u&2?3:u&4?2:0),e}},fix:function(e){if(e[v.expando])return e;var t,n,r=e,s=v.event.fixHooks[e.type]||{},o=s.props?this.props.concat(s.props):this.props;e=v.Event(r);for(t=o.length;t;)n=o[--t],e[n]=r[n];return e.target||(e.target=r.srcElement||i),e.target.nodeType===3&&(e.target=e.target.parentNode),e.metaKey=!!e.metaKey,s.filter?s.filter(e,r):e},special:{load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(e,t,n){v.isWindow(this)&&(this.onbeforeunload=n)},teardown:function(e,t){this.onbeforeunload===t&&(this.onbeforeunload=null)}}},simulate:function(e,t,n,r){var i=v.extend(new v.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?v.event.trigger(i,null,t):v.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},v.event.handle=v.event.dispatch,v.removeEvent=i.removeEventListener?function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)}:function(e,t,n){var r="on"+t;e.detachEvent&&(typeof e[r]=="undefined"&&(e[r]=null),e.detachEvent(r,n))},v.Event=function(e,t){if(!(this instanceof v.Event))return new v.Event(e,t);e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.returnValue===!1||e.getPreventDefault&&e.getPreventDefault()?tt:et):this.type=e,t&&v.extend(this,t),this.timeStamp=e&&e.timeStamp||v.now(),this[v.expando]=!0},v.Event.prototype={preventDefault:function(){this.isDefaultPrevented=tt;var e=this.originalEvent;if(!e)return;e.preventDefault?e.preventDefault():e.returnValue=!1},stopPropagation:function(){this.isPropagationStopped=tt;var e=this.originalEvent;if(!e)return;e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=tt,this.stopPropagation()},isDefaultPrevented:et,isPropagationStopped:et,isImmediatePropagationStopped:et},v.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(e,t){v.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,s=e.handleObj,o=s.selector;if(!i||i!==r&&!v.contains(r,i))e.type=s.origType,n=s.handler.apply(this,arguments),e.type=t;return n}}}),v.support.submitBubbles||(v.event.special.submit={setup:function(){if(v.nodeName(this,"form"))return!1;v.event.add(this,"click._submit keypress._submit",function(e){var n=e.target,r=v.nodeName(n,"input")||v.nodeName(n,"button")?n.form:t;r&&!v._data(r,"_submit_attached")&&(v.event.add(r,"submit._submit",function(e){e._submit_bubble=!0}),v._data(r,"_submit_attached",!0))})},postDispatch:function(e){e._submit_bubble&&(delete e._submit_bubble,this.parentNode&&!e.isTrigger&&v.event.simulate("submit",this.parentNode,e,!0))},teardown:function(){if(v.nodeName(this,"form"))return!1;v.event.remove(this,"._submit")}}),v.support.changeBubbles||(v.event.special.change={setup:function(){if($.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio")v.event.add(this,"propertychange._change",function(e){e.originalEvent.propertyName==="checked"&&(this._just_changed=!0)}),v.event.add(this,"click._change",function(e){this._just_changed&&!e.isTrigger&&(this._just_changed=!1),v.event.simulate("change",this,e,!0)});return!1}v.event.add(this,"beforeactivate._change",function(e){var t=e.target;$.test(t.nodeName)&&!v._data(t,"_change_attached")&&(v.event.add(t,"change._change",function(e){this.parentNode&&!e.isSimulated&&!e.isTrigger&&v.event.simulate("change",this.parentNode,e,!0)}),v._data(t,"_change_attached",!0))})},handle:function(e){var t=e.target;if(this!==t||e.isSimulated||e.isTrigger||t.type!=="radio"&&t.type!=="checkbox")return e.handleObj.handler.apply(this,arguments)},teardown:function(){return v.event.remove(this,"._change"),!$.test(this.nodeName)}}),v.support.focusinBubbles||v.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){v.event.simulate(t,e.target,v.event.fix(e),!0)};v.event.special[t]={setup:function(){n++===0&&i.addEventListener(e,r,!0)},teardown:function(){--n===0&&i.removeEventListener(e,r,!0)}}}),v.fn.extend({on:function(e,n,r,i,s){var o,u;if(typeof e=="object"){typeof n!="string"&&(r=r||n,n=t);for(u in e)this.on(u,n,r,e[u],s);return this}r==null&&i==null?(i=n,r=n=t):i==null&&(typeof n=="string"?(i=r,r=t):(i=r,r=n,n=t));if(i===!1)i=et;else if(!i)return this;return s===1&&(o=i,i=function(e){return v().off(e),o.apply(this,arguments)},i.guid=o.guid||(o.guid=v.guid++)),this.each(function(){v.event.add(this,e,i,r,n)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,n,r){var i,s;if(e&&e.preventDefault&&e.handleObj)return i=e.handleObj,v(e.delegateTarget).off(i.namespace?i.origType+"."+i.namespace:i.origType,i.selector,i.handler),this;if(typeof e=="object"){for(s in e)this.off(s,n,e[s]);return this}if(n===!1||typeof n=="function")r=n,n=t;return r===!1&&(r=et),this.each(function(){v.event.remove(this,e,r,n)})},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},live:function(e,t,n){return v(this.context).on(e,this.selector,t,n),this},die:function(e,t){return v(this.context).off(e,this.selector||"**",t),this},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return arguments.length===1?this.off(e,"**"):this.off(t,e||"**",n)},trigger:function(e,t){return this.each(function(){v.event.trigger(e,t,this)})},triggerHandler:function(e,t){if(this[0])return v.event.trigger(e,t,this[0],!0)},toggle:function(e){var t=arguments,n=e.guid||v.guid++,r=0,i=function(n){var i=(v._data(this,"lastToggle"+e.guid)||0)%r;return v._data(this,"lastToggle"+e.guid,i+1),n.preventDefault(),t[i].apply(this,arguments)||!1};i.guid=n;while(r<t.length)t[r++].guid=n;return this.click(i)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),v.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(e,t){v.fn[t]=function(e,n){return n==null&&(n=e,e=null),arguments.length>0?this.on(t,null,e,n):this.trigger(t)},Q.test(t)&&(v.event.fixHooks[t]=v.event.keyHooks),G.test(t)&&(v.event.fixHooks[t]=v.event.mouseHooks)}),function(e,t){function nt(e,t,n,r){n=n||[],t=t||g;var i,s,a,f,l=t.nodeType;if(!e||typeof e!="string")return n;if(l!==1&&l!==9)return[];a=o(t);if(!a&&!r)if(i=R.exec(e))if(f=i[1]){if(l===9){s=t.getElementById(f);if(!s||!s.parentNode)return n;if(s.id===f)return n.push(s),n}else if(t.ownerDocument&&(s=t.ownerDocument.getElementById(f))&&u(t,s)&&s.id===f)return n.push(s),n}else{if(i[2])return S.apply(n,x.call(t.getElementsByTagName(e),0)),n;if((f=i[3])&&Z&&t.getElementsByClassName)return S.apply(n,x.call(t.getElementsByClassName(f),0)),n}return vt(e.replace(j,"$1"),t,n,r,a)}function rt(e){return function(t){var n=t.nodeName.toLowerCase();return n==="input"&&t.type===e}}function it(e){return function(t){var n=t.nodeName.toLowerCase();return(n==="input"||n==="button")&&t.type===e}}function st(e){return N(function(t){return t=+t,N(function(n,r){var i,s=e([],n.length,t),o=s.length;while(o--)n[i=s[o]]&&(n[i]=!(r[i]=n[i]))})})}function ot(e,t,n){if(e===t)return n;var r=e.nextSibling;while(r){if(r===t)return-1;r=r.nextSibling}return 1}function ut(e,t){var n,r,s,o,u,a,f,l=L[d][e+" "];if(l)return t?0:l.slice(0);u=e,a=[],f=i.preFilter;while(u){if(!n||(r=F.exec(u)))r&&(u=u.slice(r[0].length)||u),a.push(s=[]);n=!1;if(r=I.exec(u))s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=r[0].replace(j," ");for(o in i.filter)(r=J[o].exec(u))&&(!f[o]||(r=f[o](r)))&&(s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=o,n.matches=r);if(!n)break}return t?u.length:u?nt.error(e):L(e,a).slice(0)}function at(e,t,r){var i=t.dir,s=r&&t.dir==="parentNode",o=w++;return t.first?function(t,n,r){while(t=t[i])if(s||t.nodeType===1)return e(t,n,r)}:function(t,r,u){if(!u){var a,f=b+" "+o+" ",l=f+n;while(t=t[i])if(s||t.nodeType===1){if((a=t[d])===l)return t.sizset;if(typeof a=="string"&&a.indexOf(f)===0){if(t.sizset)return t}else{t[d]=l;if(e(t,r,u))return t.sizset=!0,t;t.sizset=!1}}}else while(t=t[i])if(s||t.nodeType===1)if(e(t,r,u))return t}}function ft(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function lt(e,t,n,r,i){var s,o=[],u=0,a=e.length,f=t!=null;for(;u<a;u++)if(s=e[u])if(!n||n(s,r,i))o.push(s),f&&t.push(u);return o}function ct(e,t,n,r,i,s){return r&&!r[d]&&(r=ct(r)),i&&!i[d]&&(i=ct(i,s)),N(function(s,o,u,a){var f,l,c,h=[],p=[],d=o.length,v=s||dt(t||"*",u.nodeType?[u]:u,[]),m=e&&(s||!t)?lt(v,h,e,u,a):v,g=n?i||(s?e:d||r)?[]:o:m;n&&n(m,g,u,a);if(r){f=lt(g,p),r(f,[],u,a),l=f.length;while(l--)if(c=f[l])g[p[l]]=!(m[p[l]]=c)}if(s){if(i||e){if(i){f=[],l=g.length;while(l--)(c=g[l])&&f.push(m[l]=c);i(null,g=[],f,a)}l=g.length;while(l--)(c=g[l])&&(f=i?T.call(s,c):h[l])>-1&&(s[f]=!(o[f]=c))}}else g=lt(g===o?g.splice(d,g.length):g),i?i(null,o,g,a):S.apply(o,g)})}function ht(e){var t,n,r,s=e.length,o=i.relative[e[0].type],u=o||i.relative[" "],a=o?1:0,f=at(function(e){return e===t},u,!0),l=at(function(e){return T.call(t,e)>-1},u,!0),h=[function(e,n,r){return!o&&(r||n!==c)||((t=n).nodeType?f(e,n,r):l(e,n,r))}];for(;a<s;a++)if(n=i.relative[e[a].type])h=[at(ft(h),n)];else{n=i.filter[e[a].type].apply(null,e[a].matches);if(n[d]){r=++a;for(;r<s;r++)if(i.relative[e[r].type])break;return ct(a>1&&ft(h),a>1&&e.slice(0,a-1).join("").replace(j,"$1"),n,a<r&&ht(e.slice(a,r)),r<s&&ht(e=e.slice(r)),r<s&&e.join(""))}h.push(n)}return ft(h)}function pt(e,t){var r=t.length>0,s=e.length>0,o=function(u,a,f,l,h){var p,d,v,m=[],y=0,w="0",x=u&&[],T=h!=null,N=c,C=u||s&&i.find.TAG("*",h&&a.parentNode||a),k=b+=N==null?1:Math.E;T&&(c=a!==g&&a,n=o.el);for(;(p=C[w])!=null;w++){if(s&&p){for(d=0;v=e[d];d++)if(v(p,a,f)){l.push(p);break}T&&(b=k,n=++o.el)}r&&((p=!v&&p)&&y--,u&&x.push(p))}y+=w;if(r&&w!==y){for(d=0;v=t[d];d++)v(x,m,a,f);if(u){if(y>0)while(w--)!x[w]&&!m[w]&&(m[w]=E.call(l));m=lt(m)}S.apply(l,m),T&&!u&&m.length>0&&y+t.length>1&&nt.uniqueSort(l)}return T&&(b=k,c=N),x};return o.el=0,r?N(o):o}function dt(e,t,n){var r=0,i=t.length;for(;r<i;r++)nt(e,t[r],n);return n}function vt(e,t,n,r,s){var o,u,f,l,c,h=ut(e),p=h.length;if(!r&&h.length===1){u=h[0]=h[0].slice(0);if(u.length>2&&(f=u[0]).type==="ID"&&t.nodeType===9&&!s&&i.relative[u[1].type]){t=i.find.ID(f.matches[0].replace($,""),t,s)[0];if(!t)return n;e=e.slice(u.shift().length)}for(o=J.POS.test(e)?-1:u.length-1;o>=0;o--){f=u[o];if(i.relative[l=f.type])break;if(c=i.find[l])if(r=c(f.matches[0].replace($,""),z.test(u[0].type)&&t.parentNode||t,s)){u.splice(o,1),e=r.length&&u.join("");if(!e)return S.apply(n,x.call(r,0)),n;break}}}return a(e,h)(r,t,s,n,z.test(e)),n}function mt(){}var n,r,i,s,o,u,a,f,l,c,h=!0,p="undefined",d=("sizcache"+Math.random()).replace(".",""),m=String,g=e.document,y=g.documentElement,b=0,w=0,E=[].pop,S=[].push,x=[].slice,T=[].indexOf||function(e){var t=0,n=this.length;for(;t<n;t++)if(this[t]===e)return t;return-1},N=function(e,t){return e[d]=t==null||t,e},C=function(){var e={},t=[];return N(function(n,r){return t.push(n)>i.cacheLength&&delete e[t.shift()],e[n+" "]=r},e)},k=C(),L=C(),A=C(),O="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",_=M.replace("w","w#"),D="([*^$|!~]?=)",P="\\["+O+"*("+M+")"+O+"*(?:"+D+O+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+_+")|)|)"+O+"*\\]",H=":("+M+")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:"+P+")|[^:]|\\\\.)*|.*))\\)|)",B=":(even|odd|eq|gt|lt|nth|first|last)(?:\\("+O+"*((?:-\\d)?\\d*)"+O+"*\\)|)(?=[^-]|$)",j=new RegExp("^"+O+"+|((?:^|[^\\\\])(?:\\\\.)*)"+O+"+$","g"),F=new RegExp("^"+O+"*,"+O+"*"),I=new RegExp("^"+O+"*([\\x20\\t\\r\\n\\f>+~])"+O+"*"),q=new RegExp(H),R=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,U=/^:not/,z=/[\x20\t\r\n\f]*[+~]/,W=/:not\($/,X=/h\d/i,V=/input|select|textarea|button/i,$=/\\(?!\\)/g,J={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),NAME:new RegExp("^\\[name=['\"]?("+M+")['\"]?\\]"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+H),POS:new RegExp(B,"i"),CHILD:new RegExp("^:(only|nth|first|last)-child(?:\\("+O+"*(even|odd|(([+-]|)(\\d*)n|)"+O+"*(?:([+-]|)"+O+"*(\\d+)|))"+O+"*\\)|)","i"),needsContext:new RegExp("^"+O+"*[>+~]|"+B,"i")},K=function(e){var t=g.createElement("div");try{return e(t)}catch(n){return!1}finally{t=null}},Q=K(function(e){return e.appendChild(g.createComment("")),!e.getElementsByTagName("*").length}),G=K(function(e){return e.innerHTML="<a href='#'></a>",e.firstChild&&typeof e.firstChild.getAttribute!==p&&e.firstChild.getAttribute("href")==="#"}),Y=K(function(e){e.innerHTML="<select></select>";var t=typeof e.lastChild.getAttribute("multiple");return t!=="boolean"&&t!=="string"}),Z=K(function(e){return e.innerHTML="<div class='hidden e'></div><div class='hidden'></div>",!e.getElementsByClassName||!e.getElementsByClassName("e").length?!1:(e.lastChild.className="e",e.getElementsByClassName("e").length===2)}),et=K(function(e){e.id=d+0,e.innerHTML="<a name='"+d+"'></a><div name='"+d+"'></div>",y.insertBefore(e,y.firstChild);var t=g.getElementsByName&&g.getElementsByName(d).length===2+g.getElementsByName(d+0).length;return r=!g.getElementById(d),y.removeChild(e),t});try{x.call(y.childNodes,0)[0].nodeType}catch(tt){x=function(e){var t,n=[];for(;t=this[e];e++)n.push(t);return n}}nt.matches=function(e,t){return nt(e,null,null,t)},nt.matchesSelector=function(e,t){return nt(t,null,null,[e]).length>0},s=nt.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(i===1||i===9||i===11){if(typeof e.textContent=="string")return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=s(e)}else if(i===3||i===4)return e.nodeValue}else for(;t=e[r];r++)n+=s(t);return n},o=nt.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?t.nodeName!=="HTML":!1},u=nt.contains=y.contains?function(e,t){var n=e.nodeType===9?e.documentElement:e,r=t&&t.parentNode;return e===r||!!(r&&r.nodeType===1&&n.contains&&n.contains(r))}:y.compareDocumentPosition?function(e,t){return t&&!!(e.compareDocumentPosition(t)&16)}:function(e,t){while(t=t.parentNode)if(t===e)return!0;return!1},nt.attr=function(e,t){var n,r=o(e);return r||(t=t.toLowerCase()),(n=i.attrHandle[t])?n(e):r||Y?e.getAttribute(t):(n=e.getAttributeNode(t),n?typeof e[t]=="boolean"?e[t]?t:null:n.specified?n.value:null:null)},i=nt.selectors={cacheLength:50,createPseudo:N,match:J,attrHandle:G?{}:{href:function(e){return e.getAttribute("href",2)},type:function(e){return e.getAttribute("type")}},find:{ID:r?function(e,t,n){if(typeof t.getElementById!==p&&!n){var r=t.getElementById(e);return r&&r.parentNode?[r]:[]}}:function(e,n,r){if(typeof n.getElementById!==p&&!r){var i=n.getElementById(e);return i?i.id===e||typeof i.getAttributeNode!==p&&i.getAttributeNode("id").value===e?[i]:t:[]}},TAG:Q?function(e,t){if(typeof t.getElementsByTagName!==p)return t.getElementsByTagName(e)}:function(e,t){var n=t.getElementsByTagName(e);if(e==="*"){var r,i=[],s=0;for(;r=n[s];s++)r.nodeType===1&&i.push(r);return i}return n},NAME:et&&function(e,t){if(typeof t.getElementsByName!==p)return t.getElementsByName(name)},CLASS:Z&&function(e,t,n){if(typeof t.getElementsByClassName!==p&&!n)return t.getElementsByClassName(e)}},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace($,""),e[3]=(e[4]||e[5]||"").replace($,""),e[2]==="~="&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),e[1]==="nth"?(e[2]||nt.error(e[0]),e[3]=+(e[3]?e[4]+(e[5]||1):2*(e[2]==="even"||e[2]==="odd")),e[4]=+(e[6]+e[7]||e[2]==="odd")):e[2]&&nt.error(e[0]),e},PSEUDO:function(e){var t,n;if(J.CHILD.test(e[0]))return null;if(e[3])e[2]=e[3];else if(t=e[4])q.test(t)&&(n=ut(t,!0))&&(n=t.indexOf(")",t.length-n)-t.length)&&(t=t.slice(0,n),e[0]=e[0].slice(0,n)),e[2]=t;return e.slice(0,3)}},filter:{ID:r?function(e){return e=e.replace($,""),function(t){return t.getAttribute("id")===e}}:function(e){return e=e.replace($,""),function(t){var n=typeof t.getAttributeNode!==p&&t.getAttributeNode("id");return n&&n.value===e}},TAG:function(e){return e==="*"?function(){return!0}:(e=e.replace($,"").toLowerCase(),function(t){return t.nodeName&&t.nodeName.toLowerCase()===e})},CLASS:function(e){var t=k[d][e+" "];return t||(t=new RegExp("(^|"+O+")"+e+"("+O+"|$)"))&&k(e,function(e){return t.test(e.className||typeof e.getAttribute!==p&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r,i){var s=nt.attr(r,e);return s==null?t==="!=":t?(s+="",t==="="?s===n:t==="!="?s!==n:t==="^="?n&&s.indexOf(n)===0:t==="*="?n&&s.indexOf(n)>-1:t==="$="?n&&s.substr(s.length-n.length)===n:t==="~="?(" "+s+" ").indexOf(n)>-1:t==="|="?s===n||s.substr(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r){return e==="nth"?function(e){var t,i,s=e.parentNode;if(n===1&&r===0)return!0;if(s){i=0;for(t=s.firstChild;t;t=t.nextSibling)if(t.nodeType===1){i++;if(e===t)break}}return i-=r,i===n||i%n===0&&i/n>=0}:function(t){var n=t;switch(e){case"only":case"first":while(n=n.previousSibling)if(n.nodeType===1)return!1;if(e==="first")return!0;n=t;case"last":while(n=n.nextSibling)if(n.nodeType===1)return!1;return!0}}},PSEUDO:function(e,t){var n,r=i.pseudos[e]||i.setFilters[e.toLowerCase()]||nt.error("unsupported pseudo: "+e);return r[d]?r(t):r.length>1?(n=[e,e,"",t],i.setFilters.hasOwnProperty(e.toLowerCase())?N(function(e,n){var i,s=r(e,t),o=s.length;while(o--)i=T.call(e,s[o]),e[i]=!(n[i]=s[o])}):function(e){return r(e,0,n)}):r}},pseudos:{not:N(function(e){var t=[],n=[],r=a(e.replace(j,"$1"));return r[d]?N(function(e,t,n,i){var s,o=r(e,null,i,[]),u=e.length;while(u--)if(s=o[u])e[u]=!(t[u]=s)}):function(e,i,s){return t[0]=e,r(t,null,s,n),!n.pop()}}),has:N(function(e){return function(t){return nt(e,t).length>0}}),contains:N(function(e){return function(t){return(t.textContent||t.innerText||s(t)).indexOf(e)>-1}}),enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&!!e.checked||t==="option"&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},parent:function(e){return!i.pseudos.empty(e)},empty:function(e){var t;e=e.firstChild;while(e){if(e.nodeName>"@"||(t=e.nodeType)===3||t===4)return!1;e=e.nextSibling}return!0},header:function(e){return X.test(e.nodeName)},text:function(e){var t,n;return e.nodeName.toLowerCase()==="input"&&(t=e.type)==="text"&&((n=e.getAttribute("type"))==null||n.toLowerCase()===t)},radio:rt("radio"),checkbox:rt("checkbox"),file:rt("file"),password:rt("password"),image:rt("image"),submit:it("submit"),reset:it("reset"),button:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&e.type==="button"||t==="button"},input:function(e){return V.test(e.nodeName)},focus:function(e){var t=e.ownerDocument;return e===t.activeElement&&(!t.hasFocus||t.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},active:function(e){return e===e.ownerDocument.activeElement},first:st(function(){return[0]}),last:st(function(e,t){return[t-1]}),eq:st(function(e,t,n){return[n<0?n+t:n]}),even:st(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:st(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:st(function(e,t,n){for(var r=n<0?n+t:n;--r>=0;)e.push(r);return e}),gt:st(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}},f=y.compareDocumentPosition?function(e,t){return e===t?(l=!0,0):(!e.compareDocumentPosition||!t.compareDocumentPosition?e.compareDocumentPosition:e.compareDocumentPosition(t)&4)?-1:1}:function(e,t){if(e===t)return l=!0,0;if(e.sourceIndex&&t.sourceIndex)return e.sourceIndex-t.sourceIndex;var n,r,i=[],s=[],o=e.parentNode,u=t.parentNode,a=o;if(o===u)return ot(e,t);if(!o)return-1;if(!u)return 1;while(a)i.unshift(a),a=a.parentNode;a=u;while(a)s.unshift(a),a=a.parentNode;n=i.length,r=s.length;for(var f=0;f<n&&f<r;f++)if(i[f]!==s[f])return ot(i[f],s[f]);return f===n?ot(e,s[f],-1):ot(i[f],t,1)},[0,0].sort(f),h=!l,nt.uniqueSort=function(e){var t,n=[],r=1,i=0;l=h,e.sort(f);if(l){for(;t=e[r];r++)t===e[r-1]&&(i=n.push(r));while(i--)e.splice(n[i],1)}return e},nt.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},a=nt.compile=function(e,t){var n,r=[],i=[],s=A[d][e+" "];if(!s){t||(t=ut(e)),n=t.length;while(n--)s=ht(t[n]),s[d]?r.push(s):i.push(s);s=A(e,pt(i,r))}return s},g.querySelectorAll&&function(){var e,t=vt,n=/'|\\/g,r=/\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,i=[":focus"],s=[":active"],u=y.matchesSelector||y.mozMatchesSelector||y.webkitMatchesSelector||y.oMatchesSelector||y.msMatchesSelector;K(function(e){e.innerHTML="<select><option selected=''></option></select>",e.querySelectorAll("[selected]").length||i.push("\\["+O+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),e.querySelectorAll(":checked").length||i.push(":checked")}),K(function(e){e.innerHTML="<p test=''></p>",e.querySelectorAll("[test^='']").length&&i.push("[*^$]="+O+"*(?:\"\"|'')"),e.innerHTML="<input type='hidden'/>",e.querySelectorAll(":enabled").length||i.push(":enabled",":disabled")}),i=new RegExp(i.join("|")),vt=function(e,r,s,o,u){if(!o&&!u&&!i.test(e)){var a,f,l=!0,c=d,h=r,p=r.nodeType===9&&e;if(r.nodeType===1&&r.nodeName.toLowerCase()!=="object"){a=ut(e),(l=r.getAttribute("id"))?c=l.replace(n,"\\$&"):r.setAttribute("id",c),c="[id='"+c+"'] ",f=a.length;while(f--)a[f]=c+a[f].join("");h=z.test(e)&&r.parentNode||r,p=a.join(",")}if(p)try{return S.apply(s,x.call(h.querySelectorAll(p),0)),s}catch(v){}finally{l||r.removeAttribute("id")}}return t(e,r,s,o,u)},u&&(K(function(t){e=u.call(t,"div");try{u.call(t,"[test!='']:sizzle"),s.push("!=",H)}catch(n){}}),s=new RegExp(s.join("|")),nt.matchesSelector=function(t,n){n=n.replace(r,"='$1']");if(!o(t)&&!s.test(n)&&!i.test(n))try{var a=u.call(t,n);if(a||e||t.document&&t.document.nodeType!==11)return a}catch(f){}return nt(n,null,null,[t]).length>0})}(),i.pseudos.nth=i.pseudos.eq,i.filters=mt.prototype=i.pseudos,i.setFilters=new mt,nt.attr=v.attr,v.find=nt,v.expr=nt.selectors,v.expr[":"]=v.expr.pseudos,v.unique=nt.uniqueSort,v.text=nt.getText,v.isXMLDoc=nt.isXML,v.contains=nt.contains}(e);var nt=/Until$/,rt=/^(?:parents|prev(?:Until|All))/,it=/^.[^:#\[\.,]*$/,st=v.expr.match.needsContext,ot={children:!0,contents:!0,next:!0,prev:!0};v.fn.extend({find:function(e){var t,n,r,i,s,o,u=this;if(typeof e!="string")return v(e).filter(function(){for(t=0,n=u.length;t<n;t++)if(v.contains(u[t],this))return!0});o=this.pushStack("","find",e);for(t=0,n=this.length;t<n;t++){r=o.length,v.find(e,this[t],o);if(t>0)for(i=r;i<o.length;i++)for(s=0;s<r;s++)if(o[s]===o[i]){o.splice(i--,1);break}}return o},has:function(e){var t,n=v(e,this),r=n.length;return this.filter(function(){for(t=0;t<r;t++)if(v.contains(this,n[t]))return!0})},not:function(e){return this.pushStack(ft(this,e,!1),"not",e)},filter:function(e){return this.pushStack(ft(this,e,!0),"filter",e)},is:function(e){return!!e&&(typeof e=="string"?st.test(e)?v(e,this.context).index(this[0])>=0:v.filter(e,this).length>0:this.filter(e).length>0)},closest:function(e,t){var n,r=0,i=this.length,s=[],o=st.test(e)||typeof e!="string"?v(e,t||this.context):0;for(;r<i;r++){n=this[r];while(n&&n.ownerDocument&&n!==t&&n.nodeType!==11){if(o?o.index(n)>-1:v.find.matchesSelector(n,e)){s.push(n);break}n=n.parentNode}}return s=s.length>1?v.unique(s):s,this.pushStack(s,"closest",e)},index:function(e){return e?typeof e=="string"?v.inArray(this[0],v(e)):v.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.prevAll().length:-1},add:function(e,t){var n=typeof e=="string"?v(e,t):v.makeArray(e&&e.nodeType?[e]:e),r=v.merge(this.get(),n);return this.pushStack(ut(n[0])||ut(r[0])?r:v.unique(r))},addBack:function(e){return this.add(e==null?this.prevObject:this.prevObject.filter(e))}}),v.fn.andSelf=v.fn.addBack,v.each({parent:function(e){var t=e.parentNode;return t&&t.nodeType!==11?t:null},parents:function(e){return v.dir(e,"parentNode")},parentsUntil:function(e,t,n){return v.dir(e,"parentNode",n)},next:function(e){return at(e,"nextSibling")},prev:function(e){return at(e,"previousSibling")},nextAll:function(e){return v.dir(e,"nextSibling")},prevAll:function(e){return v.dir(e,"previousSibling")},nextUntil:function(e,t,n){return v.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return v.dir(e,"previousSibling",n)},siblings:function(e){return v.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return v.sibling(e.firstChild)},contents:function(e){return v.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:v.merge([],e.childNodes)}},function(e,t){v.fn[e]=function(n,r){var i=v.map(this,t,n);return nt.test(e)||(r=n),r&&typeof r=="string"&&(i=v.filter(r,i)),i=this.length>1&&!ot[e]?v.unique(i):i,this.length>1&&rt.test(e)&&(i=i.reverse()),this.pushStack(i,e,l.call(arguments).join(","))}}),v.extend({filter:function(e,t,n){return n&&(e=":not("+e+")"),t.length===1?v.find.matchesSelector(t[0],e)?[t[0]]:[]:v.find.matches(e,t)},dir:function(e,n,r){var i=[],s=e[n];while(s&&s.nodeType!==9&&(r===t||s.nodeType!==1||!v(s).is(r)))s.nodeType===1&&i.push(s),s=s[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)e.nodeType===1&&e!==t&&n.push(e);return n}});var ct="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",ht=/ jQuery\d+="(?:null|\d+)"/g,pt=/^\s+/,dt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,vt=/<([\w:]+)/,mt=/<tbody/i,gt=/<|&#?\w+;/,yt=/<(?:script|style|link)/i,bt=/<(?:script|object|embed|option|style)/i,wt=new RegExp("<(?:"+ct+")[\\s/>]","i"),Et=/^(?:checkbox|radio)$/,St=/checked\s*(?:[^=]|=\s*.checked.)/i,xt=/\/(java|ecma)script/i,Tt=/^\s*<!(?:\[CDATA\[|\-\-)|[\]\-]{2}>\s*$/g,Nt={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},Ct=lt(i),kt=Ct.appendChild(i.createElement("div"));Nt.optgroup=Nt.option,Nt.tbody=Nt.tfoot=Nt.colgroup=Nt.caption=Nt.thead,Nt.th=Nt.td,v.support.htmlSerialize||(Nt._default=[1,"X<div>","</div>"]),v.fn.extend({text:function(e){return v.access(this,function(e){return e===t?v.text(this):this.empty().append((this[0]&&this[0].ownerDocument||i).createTextNode(e))},null,e,arguments.length)},wrapAll:function(e){if(v.isFunction(e))return this.each(function(t){v(this).wrapAll(e.call(this,t))});if(this[0]){var t=v(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&e.firstChild.nodeType===1)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return v.isFunction(e)?this.each(function(t){v(this).wrapInner(e.call(this,t))}):this.each(function(){var t=v(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=v.isFunction(e);return this.each(function(n){v(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){v.nodeName(this,"body")||v(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.appendChild(e)})},prepend:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.insertBefore(e,this.firstChild)})},before:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(e,this),"before",this.selector)}},after:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this.nextSibling)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(this,e),"after",this.selector)}},remove:function(e,t){var n,r=0;for(;(n=this[r])!=null;r++)if(!e||v.filter(e,[n]).length)!t&&n.nodeType===1&&(v.cleanData(n.getElementsByTagName("*")),v.cleanData([n])),n.parentNode&&n.parentNode.removeChild(n);return this},empty:function(){var e,t=0;for(;(e=this[t])!=null;t++){e.nodeType===1&&v.cleanData(e.getElementsByTagName("*"));while(e.firstChild)e.removeChild(e.firstChild)}return this},clone:function(e,t){return e=e==null?!1:e,t=t==null?e:t,this.map(function(){return v.clone(this,e,t)})},html:function(e){return v.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return n.nodeType===1?n.innerHTML.replace(ht,""):t;if(typeof e=="string"&&!yt.test(e)&&(v.support.htmlSerialize||!wt.test(e))&&(v.support.leadingWhitespace||!pt.test(e))&&!Nt[(vt.exec(e)||["",""])[1].toLowerCase()]){e=e.replace(dt,"<$1></$2>");try{for(;r<i;r++)n=this[r]||{},n.nodeType===1&&(v.cleanData(n.getElementsByTagName("*")),n.innerHTML=e);n=0}catch(s){}}n&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(e){return ut(this[0])?this.length?this.pushStack(v(v.isFunction(e)?e():e),"replaceWith",e):this:v.isFunction(e)?this.each(function(t){var n=v(this),r=n.html();n.replaceWith(e.call(this,t,r))}):(typeof e!="string"&&(e=v(e).detach()),this.each(function(){var t=this.nextSibling,n=this.parentNode;v(this).remove(),t?v(t).before(e):v(n).append(e)}))},detach:function(e){return this.remove(e,!0)},domManip:function(e,n,r){e=[].concat.apply([],e);var i,s,o,u,a=0,f=e[0],l=[],c=this.length;if(!v.support.checkClone&&c>1&&typeof f=="string"&&St.test(f))return this.each(function(){v(this).domManip(e,n,r)});if(v.isFunction(f))return this.each(function(i){var s=v(this);e[0]=f.call(this,i,n?s.html():t),s.domManip(e,n,r)});if(this[0]){i=v.buildFragment(e,this,l),o=i.fragment,s=o.firstChild,o.childNodes.length===1&&(o=s);if(s){n=n&&v.nodeName(s,"tr");for(u=i.cacheable||c-1;a<c;a++)r.call(n&&v.nodeName(this[a],"table")?Lt(this[a],"tbody"):this[a],a===u?o:v.clone(o,!0,!0))}o=s=null,l.length&&v.each(l,function(e,t){t.src?v.ajax?v.ajax({url:t.src,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0}):v.error("no ajax"):v.globalEval((t.text||t.textContent||t.innerHTML||"").replace(Tt,"")),t.parentNode&&t.parentNode.removeChild(t)})}return this}}),v.buildFragment=function(e,n,r){var s,o,u,a=e[0];return n=n||i,n=!n.nodeType&&n[0]||n,n=n.ownerDocument||n,e.length===1&&typeof a=="string"&&a.length<512&&n===i&&a.charAt(0)==="<"&&!bt.test(a)&&(v.support.checkClone||!St.test(a))&&(v.support.html5Clone||!wt.test(a))&&(o=!0,s=v.fragments[a],u=s!==t),s||(s=n.createDocumentFragment(),v.clean(e,n,s,r),o&&(v.fragments[a]=u&&s)),{fragment:s,cacheable:o}},v.fragments={},v.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){v.fn[e]=function(n){var r,i=0,s=[],o=v(n),u=o.length,a=this.length===1&&this[0].parentNode;if((a==null||a&&a.nodeType===11&&a.childNodes.length===1)&&u===1)return o[t](this[0]),this;for(;i<u;i++)r=(i>0?this.clone(!0):this).get(),v(o[i])[t](r),s=s.concat(r);return this.pushStack(s,e,o.selector)}}),v.extend({clone:function(e,t,n){var r,i,s,o;v.support.html5Clone||v.isXMLDoc(e)||!wt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(kt.innerHTML=e.outerHTML,kt.removeChild(o=kt.firstChild));if((!v.support.noCloneEvent||!v.support.noCloneChecked)&&(e.nodeType===1||e.nodeType===11)&&!v.isXMLDoc(e)){Ot(e,o),r=Mt(e),i=Mt(o);for(s=0;r[s];++s)i[s]&&Ot(r[s],i[s])}if(t){At(e,o);if(n){r=Mt(e),i=Mt(o);for(s=0;r[s];++s)At(r[s],i[s])}}return r=i=null,o},clean:function(e,t,n,r){var s,o,u,a,f,l,c,h,p,d,m,g,y=t===i&&Ct,b=[];if(!t||typeof t.createDocumentFragment=="undefined")t=i;for(s=0;(u=e[s])!=null;s++){typeof u=="number"&&(u+="");if(!u)continue;if(typeof u=="string")if(!gt.test(u))u=t.createTextNode(u);else{y=y||lt(t),c=t.createElement("div"),y.appendChild(c),u=u.replace(dt,"<$1></$2>"),a=(vt.exec(u)||["",""])[1].toLowerCase(),f=Nt[a]||Nt._default,l=f[0],c.innerHTML=f[1]+u+f[2];while(l--)c=c.lastChild;if(!v.support.tbody){h=mt.test(u),p=a==="table"&&!h?c.firstChild&&c.firstChild.childNodes:f[1]==="<table>"&&!h?c.childNodes:[];for(o=p.length-1;o>=0;--o)v.nodeName(p[o],"tbody")&&!p[o].childNodes.length&&p[o].parentNode.removeChild(p[o])}!v.support.leadingWhitespace&&pt.test(u)&&c.insertBefore(t.createTextNode(pt.exec(u)[0]),c.firstChild),u=c.childNodes,c.parentNode.removeChild(c)}u.nodeType?b.push(u):v.merge(b,u)}c&&(u=c=y=null);if(!v.support.appendChecked)for(s=0;(u=b[s])!=null;s++)v.nodeName(u,"input")?_t(u):typeof u.getElementsByTagName!="undefined"&&v.grep(u.getElementsByTagName("input"),_t);if(n){m=function(e){if(!e.type||xt.test(e.type))return r?r.push(e.parentNode?e.parentNode.removeChild(e):e):n.appendChild(e)};for(s=0;(u=b[s])!=null;s++)if(!v.nodeName(u,"script")||!m(u))n.appendChild(u),typeof u.getElementsByTagName!="undefined"&&(g=v.grep(v.merge([],u.getElementsByTagName("script")),m),b.splice.apply(b,[s+1,0].concat(g)),s+=g.length)}return b},cleanData:function(e,t){var n,r,i,s,o=0,u=v.expando,a=v.cache,f=v.support.deleteExpando,l=v.event.special;for(;(i=e[o])!=null;o++)if(t||v.acceptData(i)){r=i[u],n=r&&a[r];if(n){if(n.events)for(s in n.events)l[s]?v.event.remove(i,s):v.removeEvent(i,s,n.handle);a[r]&&(delete a[r],f?delete i[u]:i.removeAttribute?i.removeAttribute(u):i[u]=null,v.deletedIds.push(r))}}}}),function(){var e,t;v.uaMatch=function(e){e=e.toLowerCase();var t=/(chrome)[ \/]([\w.]+)/.exec(e)||/(webkit)[ \/]([\w.]+)/.exec(e)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(e)||/(msie) ([\w.]+)/.exec(e)||e.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(e)||[];return{browser:t[1]||"",version:t[2]||"0"}},e=v.uaMatch(o.userAgent),t={},e.browser&&(t[e.browser]=!0,t.version=e.version),t.chrome?t.webkit=!0:t.webkit&&(t.safari=!0),v.browser=t,v.sub=function(){function e(t,n){return new e.fn.init(t,n)}v.extend(!0,e,this),e.superclass=this,e.fn=e.prototype=this(),e.fn.constructor=e,e.sub=this.sub,e.fn.init=function(r,i){return i&&i instanceof v&&!(i instanceof e)&&(i=e(i)),v.fn.init.call(this,r,i,t)},e.fn.init.prototype=e.fn;var t=e(i);return e}}();var Dt,Pt,Ht,Bt=/alpha\([^)]*\)/i,jt=/opacity=([^)]*)/,Ft=/^(top|right|bottom|left)$/,It=/^(none|table(?!-c[ea]).+)/,qt=/^margin/,Rt=new RegExp("^("+m+")(.*)$","i"),Ut=new RegExp("^("+m+")(?!px)[a-z%]+$","i"),zt=new RegExp("^([-+])=("+m+")","i"),Wt={BODY:"block"},Xt={position:"absolute",visibility:"hidden",display:"block"},Vt={letterSpacing:0,fontWeight:400},$t=["Top","Right","Bottom","Left"],Jt=["Webkit","O","Moz","ms"],Kt=v.fn.toggle;v.fn.extend({css:function(e,n){return v.access(this,function(e,n,r){return r!==t?v.style(e,n,r):v.css(e,n)},e,n,arguments.length>1)},show:function(){return Yt(this,!0)},hide:function(){return Yt(this)},toggle:function(e,t){var n=typeof e=="boolean";return v.isFunction(e)&&v.isFunction(t)?Kt.apply(this,arguments):this.each(function(){(n?e:Gt(this))?v(this).show():v(this).hide()})}}),v.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Dt(e,"opacity");return n===""?"1":n}}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":v.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(!e||e.nodeType===3||e.nodeType===8||!e.style)return;var s,o,u,a=v.camelCase(n),f=e.style;n=v.cssProps[a]||(v.cssProps[a]=Qt(f,a)),u=v.cssHooks[n]||v.cssHooks[a];if(r===t)return u&&"get"in u&&(s=u.get(e,!1,i))!==t?s:f[n];o=typeof r,o==="string"&&(s=zt.exec(r))&&(r=(s[1]+1)*s[2]+parseFloat(v.css(e,n)),o="number");if(r==null||o==="number"&&isNaN(r))return;o==="number"&&!v.cssNumber[a]&&(r+="px");if(!u||!("set"in u)||(r=u.set(e,r,i))!==t)try{f[n]=r}catch(l){}},css:function(e,n,r,i){var s,o,u,a=v.camelCase(n);return n=v.cssProps[a]||(v.cssProps[a]=Qt(e.style,a)),u=v.cssHooks[n]||v.cssHooks[a],u&&"get"in u&&(s=u.get(e,!0,i)),s===t&&(s=Dt(e,n)),s==="normal"&&n in Vt&&(s=Vt[n]),r||i!==t?(o=parseFloat(s),r||v.isNumeric(o)?o||0:s):s},swap:function(e,t,n){var r,i,s={};for(i in t)s[i]=e.style[i],e.style[i]=t[i];r=n.call(e);for(i in t)e.style[i]=s[i];return r}}),e.getComputedStyle?Dt=function(t,n){var r,i,s,o,u=e.getComputedStyle(t,null),a=t.style;return u&&(r=u.getPropertyValue(n)||u[n],r===""&&!v.contains(t.ownerDocument,t)&&(r=v.style(t,n)),Ut.test(r)&&qt.test(n)&&(i=a.width,s=a.minWidth,o=a.maxWidth,a.minWidth=a.maxWidth=a.width=r,r=u.width,a.width=i,a.minWidth=s,a.maxWidth=o)),r}:i.documentElement.currentStyle&&(Dt=function(e,t){var n,r,i=e.currentStyle&&e.currentStyle[t],s=e.style;return i==null&&s&&s[t]&&(i=s[t]),Ut.test(i)&&!Ft.test(t)&&(n=s.left,r=e.runtimeStyle&&e.runtimeStyle.left,r&&(e.runtimeStyle.left=e.currentStyle.left),s.left=t==="fontSize"?"1em":i,i=s.pixelLeft+"px",s.left=n,r&&(e.runtimeStyle.left=r)),i===""?"auto":i}),v.each(["height","width"],function(e,t){v.cssHooks[t]={get:function(e,n,r){if(n)return e.offsetWidth===0&&It.test(Dt(e,"display"))?v.swap(e,Xt,function(){return tn(e,t,r)}):tn(e,t,r)},set:function(e,n,r){return Zt(e,n,r?en(e,t,r,v.support.boxSizing&&v.css(e,"boxSizing")==="border-box"):0)}}}),v.support.opacity||(v.cssHooks.opacity={get:function(e,t){return jt.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,r=e.currentStyle,i=v.isNumeric(t)?"alpha(opacity="+t*100+")":"",s=r&&r.filter||n.filter||"";n.zoom=1;if(t>=1&&v.trim(s.replace(Bt,""))===""&&n.removeAttribute){n.removeAttribute("filter");if(r&&!r.filter)return}n.filter=Bt.test(s)?s.replace(Bt,i):s+" "+i}}),v(function(){v.support.reliableMarginRight||(v.cssHooks.marginRight={get:function(e,t){return v.swap(e,{display:"inline-block"},function(){if(t)return Dt(e,"marginRight")})}}),!v.support.pixelPosition&&v.fn.position&&v.each(["top","left"],function(e,t){v.cssHooks[t]={get:function(e,n){if(n){var r=Dt(e,t);return Ut.test(r)?v(e).position()[t]+"px":r}}}})}),v.expr&&v.expr.filters&&(v.expr.filters.hidden=function(e){return e.offsetWidth===0&&e.offsetHeight===0||!v.support.reliableHiddenOffsets&&(e.style&&e.style.display||Dt(e,"display"))==="none"},v.expr.filters.visible=function(e){return!v.expr.filters.hidden(e)}),v.each({margin:"",padding:"",border:"Width"},function(e,t){v.cssHooks[e+t]={expand:function(n){var r,i=typeof n=="string"?n.split(" "):[n],s={};for(r=0;r<4;r++)s[e+$t[r]+t]=i[r]||i[r-2]||i[0];return s}},qt.test(e)||(v.cssHooks[e+t].set=Zt)});var rn=/%20/g,sn=/\[\]$/,on=/\r?\n/g,un=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,an=/^(?:select|textarea)/i;v.fn.extend({serialize:function(){return v.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?v.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||an.test(this.nodeName)||un.test(this.type))}).map(function(e,t){var n=v(this).val();return n==null?null:v.isArray(n)?v.map(n,function(e,n){return{name:t.name,value:e.replace(on,"\r\n")}}):{name:t.name,value:n.replace(on,"\r\n")}}).get()}}),v.param=function(e,n){var r,i=[],s=function(e,t){t=v.isFunction(t)?t():t==null?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};n===t&&(n=v.ajaxSettings&&v.ajaxSettings.traditional);if(v.isArray(e)||e.jquery&&!v.isPlainObject(e))v.each(e,function(){s(this.name,this.value)});else for(r in e)fn(r,e[r],n,s);return i.join("&").replace(rn,"+")};var ln,cn,hn=/#.*$/,pn=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,dn=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,vn=/^(?:GET|HEAD)$/,mn=/^\/\//,gn=/\?/,yn=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bn=/([?&])_=[^&]*/,wn=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,En=v.fn.load,Sn={},xn={},Tn=["*/"]+["*"];try{cn=s.href}catch(Nn){cn=i.createElement("a"),cn.href="",cn=cn.href}ln=wn.exec(cn.toLowerCase())||[],v.fn.load=function(e,n,r){if(typeof e!="string"&&En)return En.apply(this,arguments);if(!this.length)return this;var i,s,o,u=this,a=e.indexOf(" ");return a>=0&&(i=e.slice(a,e.length),e=e.slice(0,a)),v.isFunction(n)?(r=n,n=t):n&&typeof n=="object"&&(s="POST"),v.ajax({url:e,type:s,dataType:"html",data:n,complete:function(e,t){r&&u.each(r,o||[e.responseText,t,e])}}).done(function(e){o=arguments,u.html(i?v("<div>").append(e.replace(yn,"")).find(i):e)}),this},v.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(e,t){v.fn[t]=function(e){return this.on(t,e)}}),v.each(["get","post"],function(e,n){v[n]=function(e,r,i,s){return v.isFunction(r)&&(s=s||i,i=r,r=t),v.ajax({type:n,url:e,data:r,success:i,dataType:s})}}),v.extend({getScript:function(e,n){return v.get(e,t,n,"script")},getJSON:function(e,t,n){return v.get(e,t,n,"json")},ajaxSetup:function(e,t){return t?Ln(e,v.ajaxSettings):(t=e,e=v.ajaxSettings),Ln(e,t),e},ajaxSettings:{url:cn,isLocal:dn.test(ln[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":Tn},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":e.String,"text html":!0,"text json":v.parseJSON,"text xml":v.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:Cn(Sn),ajaxTransport:Cn(xn),ajax:function(e,n){function T(e,n,s,a){var l,y,b,w,S,T=n;if(E===2)return;E=2,u&&clearTimeout(u),o=t,i=a||"",x.readyState=e>0?4:0,s&&(w=An(c,x,s));if(e>=200&&e<300||e===304)c.ifModified&&(S=x.getResponseHeader("Last-Modified"),S&&(v.lastModified[r]=S),S=x.getResponseHeader("Etag"),S&&(v.etag[r]=S)),e===304?(T="notmodified",l=!0):(l=On(c,w),T=l.state,y=l.data,b=l.error,l=!b);else{b=T;if(!T||e)T="error",e<0&&(e=0)}x.status=e,x.statusText=(n||T)+"",l?d.resolveWith(h,[y,T,x]):d.rejectWith(h,[x,T,b]),x.statusCode(g),g=t,f&&p.trigger("ajax"+(l?"Success":"Error"),[x,c,l?y:b]),m.fireWith(h,[x,T]),f&&(p.trigger("ajaxComplete",[x,c]),--v.active||v.event.trigger("ajaxStop"))}typeof e=="object"&&(n=e,e=t),n=n||{};var r,i,s,o,u,a,f,l,c=v.ajaxSetup({},n),h=c.context||c,p=h!==c&&(h.nodeType||h instanceof v)?v(h):v.event,d=v.Deferred(),m=v.Callbacks("once memory"),g=c.statusCode||{},b={},w={},E=0,S="canceled",x={readyState:0,setRequestHeader:function(e,t){if(!E){var n=e.toLowerCase();e=w[n]=w[n]||e,b[e]=t}return this},getAllResponseHeaders:function(){return E===2?i:null},getResponseHeader:function(e){var n;if(E===2){if(!s){s={};while(n=pn.exec(i))s[n[1].toLowerCase()]=n[2]}n=s[e.toLowerCase()]}return n===t?null:n},overrideMimeType:function(e){return E||(c.mimeType=e),this},abort:function(e){return e=e||S,o&&o.abort(e),T(0,e),this}};d.promise(x),x.success=x.done,x.error=x.fail,x.complete=m.add,x.statusCode=function(e){if(e){var t;if(E<2)for(t in e)g[t]=[g[t],e[t]];else t=e[x.status],x.always(t)}return this},c.url=((e||c.url)+"").replace(hn,"").replace(mn,ln[1]+"//"),c.dataTypes=v.trim(c.dataType||"*").toLowerCase().split(y),c.crossDomain==null&&(a=wn.exec(c.url.toLowerCase()),c.crossDomain=!(!a||a[1]===ln[1]&&a[2]===ln[2]&&(a[3]||(a[1]==="http:"?80:443))==(ln[3]||(ln[1]==="http:"?80:443)))),c.data&&c.processData&&typeof c.data!="string"&&(c.data=v.param(c.data,c.traditional)),kn(Sn,c,n,x);if(E===2)return x;f=c.global,c.type=c.type.toUpperCase(),c.hasContent=!vn.test(c.type),f&&v.active++===0&&v.event.trigger("ajaxStart");if(!c.hasContent){c.data&&(c.url+=(gn.test(c.url)?"&":"?")+c.data,delete c.data),r=c.url;if(c.cache===!1){var N=v.now(),C=c.url.replace(bn,"$1_="+N);c.url=C+(C===c.url?(gn.test(c.url)?"&":"?")+"_="+N:"")}}(c.data&&c.hasContent&&c.contentType!==!1||n.contentType)&&x.setRequestHeader("Content-Type",c.contentType),c.ifModified&&(r=r||c.url,v.lastModified[r]&&x.setRequestHeader("If-Modified-Since",v.lastModified[r]),v.etag[r]&&x.setRequestHeader("If-None-Match",v.etag[r])),x.setRequestHeader("Accept",c.dataTypes[0]&&c.accepts[c.dataTypes[0]]?c.accepts[c.dataTypes[0]]+(c.dataTypes[0]!=="*"?", "+Tn+"; q=0.01":""):c.accepts["*"]);for(l in c.headers)x.setRequestHeader(l,c.headers[l]);if(!c.beforeSend||c.beforeSend.call(h,x,c)!==!1&&E!==2){S="abort";for(l in{success:1,error:1,complete:1})x[l](c[l]);o=kn(xn,c,n,x);if(!o)T(-1,"No Transport");else{x.readyState=1,f&&p.trigger("ajaxSend",[x,c]),c.async&&c.timeout>0&&(u=setTimeout(function(){x.abort("timeout")},c.timeout));try{E=1,o.send(b,T)}catch(k){if(!(E<2))throw k;T(-1,k)}}return x}return x.abort()},active:0,lastModified:{},etag:{}});var Mn=[],_n=/\?/,Dn=/(=)\?(?=&|$)|\?\?/,Pn=v.now();v.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Mn.pop()||v.expando+"_"+Pn++;return this[e]=!0,e}}),v.ajaxPrefilter("json jsonp",function(n,r,i){var s,o,u,a=n.data,f=n.url,l=n.jsonp!==!1,c=l&&Dn.test(f),h=l&&!c&&typeof a=="string"&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Dn.test(a);if(n.dataTypes[0]==="jsonp"||c||h)return s=n.jsonpCallback=v.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,o=e[s],c?n.url=f.replace(Dn,"$1"+s):h?n.data=a.replace(Dn,"$1"+s):l&&(n.url+=(_n.test(f)?"&":"?")+n.jsonp+"="+s),n.converters["script json"]=function(){return u||v.error(s+" was not called"),u[0]},n.dataTypes[0]="json",e[s]=function(){u=arguments},i.always(function(){e[s]=o,n[s]&&(n.jsonpCallback=r.jsonpCallback,Mn.push(s)),u&&v.isFunction(o)&&o(u[0]),u=o=t}),"script"}),v.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(e){return v.globalEval(e),e}}}),v.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),v.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=i.head||i.getElementsByTagName("head")[0]||i.documentElement;return{send:function(s,o){n=i.createElement("script"),n.async="async",e.scriptCharset&&(n.charset=e.scriptCharset),n.src=e.url,n.onload=n.onreadystatechange=function(e,i){if(i||!n.readyState||/loaded|complete/.test(n.readyState))n.onload=n.onreadystatechange=null,r&&n.parentNode&&r.removeChild(n),n=t,i||o(200,"success")},r.insertBefore(n,r.firstChild)},abort:function(){n&&n.onload(0,1)}}}});var Hn,Bn=e.ActiveXObject?function(){for(var e in Hn)Hn[e](0,1)}:!1,jn=0;v.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&Fn()||In()}:Fn,function(e){v.extend(v.support,{ajax:!!e,cors:!!e&&"withCredentials"in e})}(v.ajaxSettings.xhr()),v.support.ajax&&v.ajaxTransport(function(n){if(!n.crossDomain||v.support.cors){var r;return{send:function(i,s){var o,u,a=n.xhr();n.username?a.open(n.type,n.url,n.async,n.username,n.password):a.open(n.type,n.url,n.async);if(n.xhrFields)for(u in n.xhrFields)a[u]=n.xhrFields[u];n.mimeType&&a.overrideMimeType&&a.overrideMimeType(n.mimeType),!n.crossDomain&&!i["X-Requested-With"]&&(i["X-Requested-With"]="XMLHttpRequest");try{for(u in i)a.setRequestHeader(u,i[u])}catch(f){}a.send(n.hasContent&&n.data||null),r=function(e,i){var u,f,l,c,h;try{if(r&&(i||a.readyState===4)){r=t,o&&(a.onreadystatechange=v.noop,Bn&&delete Hn[o]);if(i)a.readyState!==4&&a.abort();else{u=a.status,l=a.getAllResponseHeaders(),c={},h=a.responseXML,h&&h.documentElement&&(c.xml=h);try{c.text=a.responseText}catch(p){}try{f=a.statusText}catch(p){f=""}!u&&n.isLocal&&!n.crossDomain?u=c.text?200:404:u===1223&&(u=204)}}}catch(d){i||s(-1,d)}c&&s(u,f,c,l)},n.async?a.readyState===4?setTimeout(r,0):(o=++jn,Bn&&(Hn||(Hn={},v(e).unload(Bn)),Hn[o]=r),a.onreadystatechange=r):r()},abort:function(){r&&r(0,1)}}}});var qn,Rn,Un=/^(?:toggle|show|hide)$/,zn=new RegExp("^(?:([-+])=|)("+m+")([a-z%]*)$","i"),Wn=/queueHooks$/,Xn=[Gn],Vn={"*":[function(e,t){var n,r,i=this.createTween(e,t),s=zn.exec(t),o=i.cur(),u=+o||0,a=1,f=20;if(s){n=+s[2],r=s[3]||(v.cssNumber[e]?"":"px");if(r!=="px"&&u){u=v.css(i.elem,e,!0)||n||1;do a=a||".5",u/=a,v.style(i.elem,e,u+r);while(a!==(a=i.cur()/o)&&a!==1&&--f)}i.unit=r,i.start=u,i.end=s[1]?u+(s[1]+1)*n:n}return i}]};v.Animation=v.extend(Kn,{tweener:function(e,t){v.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;r<i;r++)n=e[r],Vn[n]=Vn[n]||[],Vn[n].unshift(t)},prefilter:function(e,t){t?Xn.unshift(e):Xn.push(e)}}),v.Tween=Yn,Yn.prototype={constructor:Yn,init:function(e,t,n,r,i,s){this.elem=e,this.prop=n,this.easing=i||"swing",this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=s||(v.cssNumber[n]?"":"px")},cur:function(){var e=Yn.propHooks[this.prop];return e&&e.get?e.get(this):Yn.propHooks._default.get(this)},run:function(e){var t,n=Yn.propHooks[this.prop];return this.options.duration?this.pos=t=v.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):Yn.propHooks._default.set(this),this}},Yn.prototype.init.prototype=Yn.prototype,Yn.propHooks={_default:{get:function(e){var t;return e.elem[e.prop]==null||!!e.elem.style&&e.elem.style[e.prop]!=null?(t=v.css(e.elem,e.prop,!1,""),!t||t==="auto"?0:t):e.elem[e.prop]},set:function(e){v.fx.step[e.prop]?v.fx.step[e.prop](e):e.elem.style&&(e.elem.style[v.cssProps[e.prop]]!=null||v.cssHooks[e.prop])?v.style(e.elem,e.prop,e.now+e.unit):e.elem[e.prop]=e.now}}},Yn.propHooks.scrollTop=Yn.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},v.each(["toggle","show","hide"],function(e,t){var n=v.fn[t];v.fn[t]=function(r,i,s){return r==null||typeof r=="boolean"||!e&&v.isFunction(r)&&v.isFunction(i)?n.apply(this,arguments):this.animate(Zn(t,!0),r,i,s)}}),v.fn.extend({fadeTo:function(e,t,n,r){return this.filter(Gt).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=v.isEmptyObject(e),s=v.speed(t,n,r),o=function(){var t=Kn(this,v.extend({},e),s);i&&t.stop(!0)};return i||s.queue===!1?this.each(o):this.queue(s.queue,o)},stop:function(e,n,r){var i=function(e){var t=e.stop;delete e.stop,t(r)};return typeof e!="string"&&(r=n,n=e,e=t),n&&e!==!1&&this.queue(e||"fx",[]),this.each(function(){var t=!0,n=e!=null&&e+"queueHooks",s=v.timers,o=v._data(this);if(n)o[n]&&o[n].stop&&i(o[n]);else for(n in o)o[n]&&o[n].stop&&Wn.test(n)&&i(o[n]);for(n=s.length;n--;)s[n].elem===this&&(e==null||s[n].queue===e)&&(s[n].anim.stop(r),t=!1,s.splice(n,1));(t||!r)&&v.dequeue(this,e)})}}),v.each({slideDown:Zn("show"),slideUp:Zn("hide"),slideToggle:Zn("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){v.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),v.speed=function(e,t,n){var r=e&&typeof e=="object"?v.extend({},e):{complete:n||!n&&t||v.isFunction(e)&&e,duration:e,easing:n&&t||t&&!v.isFunction(t)&&t};r.duration=v.fx.off?0:typeof r.duration=="number"?r.duration:r.duration in v.fx.speeds?v.fx.speeds[r.duration]:v.fx.speeds._default;if(r.queue==null||r.queue===!0)r.queue="fx";return r.old=r.complete,r.complete=function(){v.isFunction(r.old)&&r.old.call(this),r.queue&&v.dequeue(this,r.queue)},r},v.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2}},v.timers=[],v.fx=Yn.prototype.init,v.fx.tick=function(){var e,n=v.timers,r=0;qn=v.now();for(;r<n.length;r++)e=n[r],!e()&&n[r]===e&&n.splice(r--,1);n.length||v.fx.stop(),qn=t},v.fx.timer=function(e){e()&&v.timers.push(e)&&!Rn&&(Rn=setInterval(v.fx.tick,v.fx.interval))},v.fx.interval=13,v.fx.stop=function(){clearInterval(Rn),Rn=null},v.fx.speeds={slow:600,fast:200,_default:400},v.fx.step={},v.expr&&v.expr.filters&&(v.expr.filters.animated=function(e){return v.grep(v.timers,function(t){return e===t.elem}).length});var er=/^(?:body|html)$/i;v.fn.offset=function(e){if(arguments.length)return e===t?this:this.each(function(t){v.offset.setOffset(this,e,t)});var n,r,i,s,o,u,a,f={top:0,left:0},l=this[0],c=l&&l.ownerDocument;if(!c)return;return(r=c.body)===l?v.offset.bodyOffset(l):(n=c.documentElement,v.contains(n,l)?(typeof l.getBoundingClientRect!="undefined"&&(f=l.getBoundingClientRect()),i=tr(c),s=n.clientTop||r.clientTop||0,o=n.clientLeft||r.clientLeft||0,u=i.pageYOffset||n.scrollTop,a=i.pageXOffset||n.scrollLeft,{top:f.top+u-s,left:f.left+a-o}):f)},v.offset={bodyOffset:function(e){var t=e.offsetTop,n=e.offsetLeft;return v.support.doesNotIncludeMarginInBodyOffset&&(t+=parseFloat(v.css(e,"marginTop"))||0,n+=parseFloat(v.css(e,"marginLeft"))||0),{top:t,left:n}},setOffset:function(e,t,n){var r=v.css(e,"position");r==="static"&&(e.style.position="relative");var i=v(e),s=i.offset(),o=v.css(e,"top"),u=v.css(e,"left"),a=(r==="absolute"||r==="fixed")&&v.inArray("auto",[o,u])>-1,f={},l={},c,h;a?(l=i.position(),c=l.top,h=l.left):(c=parseFloat(o)||0,h=parseFloat(u)||0),v.isFunction(t)&&(t=t.call(e,n,s)),t.top!=null&&(f.top=t.top-s.top+c),t.left!=null&&(f.left=t.left-s.left+h),"using"in t?t.using.call(e,f):i.css(f)}},v.fn.extend({position:function(){if(!this[0])return;var e=this[0],t=this.offsetParent(),n=this.offset(),r=er.test(t[0].nodeName)?{top:0,left:0}:t.offset();return n.top-=parseFloat(v.css(e,"marginTop"))||0,n.left-=parseFloat(v.css(e,"marginLeft"))||0,r.top+=parseFloat(v.css(t[0],"borderTopWidth"))||0,r.left+=parseFloat(v.css(t[0],"borderLeftWidth"))||0,{top:n.top-r.top,left:n.left-r.left}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||i.body;while(e&&!er.test(e.nodeName)&&v.css(e,"position")==="static")e=e.offsetParent;return e||i.body})}}),v.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);v.fn[e]=function(i){return v.access(this,function(e,i,s){var o=tr(e);if(s===t)return o?n in o?o[n]:o.document.documentElement[i]:e[i];o?o.scrollTo(r?v(o).scrollLeft():s,r?s:v(o).scrollTop()):e[i]=s},e,i,arguments.length,null)}}),v.each({Height:"height",Width:"width"},function(e,n){v.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){v.fn[i]=function(i,s){var o=arguments.length&&(r||typeof i!="boolean"),u=r||(i===!0||s===!0?"margin":"border");return v.access(this,function(n,r,i){var s;return v.isWindow(n)?n.document.documentElement["client"+e]:n.nodeType===9?(s=n.documentElement,Math.max(n.body["scroll"+e],s["scroll"+e],n.body["offset"+e],s["offset"+e],s["client"+e])):i===t?v.css(n,r,i,u):v.style(n,r,i,u)},n,o?i:t,o,null)}})}),e.jQuery=e.$=v,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return v})})(window);</script>
<script type="text/javascript">/*!
* toc - jQuery Table of Contents Plugin
* v0.3.2
* http://projects.jga.me/toc/
* copyright Greg Allen 2017
* MIT License
*/
!function(a){a.fn.smoothScroller=function(b){b=a.extend({},a.fn.smoothScroller.defaults,b);
var c=a(this);
return a(b.scrollEl).animate({scrollTop:c.offset().top-a(b.scrollEl).offset().top-b.offset},b.speed,b.ease,function(){var a=c.attr("id");a.length&&(history.pushState?history.pushState(null,null,"#"+a):document.location.hash=a),c.trigger("smoothScrollerComplete")}),this},a.fn.smoothScroller.defaults={speed:400,ease:"swing",scrollEl:"body,html",offset:0},a("body").on("click","[data-smoothscroller]",function(b){b.preventDefault();var c=a(this).attr("href");0===c.indexOf("#")&&a(c).smoothScroller()})}(jQuery),function(a){var b={};a.fn.toc=function(b){var c,d=this,e=a.extend({},jQuery.fn.toc.defaults,b),f=a(e.container),g=a(e.selectors,f),h=[],i=e.activeClass,j=function(b,c){if(e.smoothScrolling&&"function"==typeof e.smoothScrolling){b.preventDefault();var f=a(b.target).attr("href");e.smoothScrolling(f,e,c)}a("li",d).removeClass(i),a(b.target).parent().addClass(i)},k=function(b){c&&clearTimeout(c),c=setTimeout(function(){for(var b,c=a(window).scrollTop(),f=Number.MAX_VALUE,g=0,j=0,k=h.length;j<k;j++){var l=Math.abs(h[j]-c);l<f&&(g=j,f=l)}a("li",d).removeClass(i),b=a("li:eq("+g+")",d).addClass(i),e.onHighlight(b)},50)};return e.highlightOnScroll&&(a(window).bind("scroll",k),k()),this.each(function(){var b=a(this),c=a(e.listType);g.each(function(d,f){var g=a(f);h.push(g.offset().top-e.highlightOffset);var i=e.anchorName(d,f,e.prefix);if(f.id!==i)if(f.id){a("<span/>").attr("id",i).insertBefore(g)}else f.id=i;var l=a("<a/>").text(e.headerText(d,f,g)).attr("href","#"+i).bind("click",function(c){a(window).unbind("scroll",k),j(c,function(){a(window).bind("scroll",k)}),b.trigger("selected",a(this).attr("href"))}),m=a("<li/>").addClass(e.itemClass(d,f,g,e.prefix)).append(l);c.append(m)}),b.html(c)})},jQuery.fn.toc.defaults={container:"body",listType:"<ul/>",selectors:"h1,h2,h3",smoothScrolling:function(b,c,d){a(b).smoothScroller({offset:c.scrollToOffset}).on("smoothScrollerComplete",function(){d()})},scrollToOffset:0,prefix:"toc",activeClass:"toc-active",onHighlight:function(){},highlightOnScroll:!0,highlightOffset:100,anchorName:function(c,d,e){if(d.id.length)return d.id;var f=a(d).text().replace(/[^a-z0-9]/gi," ").replace(/\s+/g,"-").toLowerCase();if(b[f]){for(var g=2;b[f+g];)g++;f=f+"-"+g}return b[f]=!0,e+"-"+f},headerText:function(a,b,c){return c.data("toc-title")||c.text()},itemClass:function(a,b,c,d){return d+"-"+c[0].tagName.toLowerCase()}}}(jQuery);</script>
<script type="text/javascript">
function isElementInViewport (el) {
if (typeof jQuery === "function" && el instanceof jQuery) {
el = el[0];
}
var rect = el.getBoundingClientRect();
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */
rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */
);
}
$(function(){
$('#table-of-contents').toc({
'highlightOffset': 0,
'smoothScrolling': function(target, options, callback) {
var oldHist = history.pushState;
var shouldRestore = false;
history.pushState = null;
$(target).smoothScroller({
offset: options.scrollToOffset
}).on('smoothScrollerComplete', function() {
callback();
if (shouldRestore) {
history.pushState = oldHist;
}
shouldRestore = true;
});
},
'onHighlight': function(el) {
el.addClass('visited_after_load');
if (!isElementInViewport(el)) {
$('#table-of-contents').animate({
scrollTop: el.offset().top
}, 1000);
}
}
});
});
</script>
<script type="text/javascript">
function CodeHighlightOn(elem, id)
{
var target = document.getElementById(id);
if(null != target) {
elem.cacheClassElem = elem.className;
elem.cacheClassTarget = target.className;
target.className = "code-highlighted";
elem.className = "code-highlighted";
}
}
function CodeHighlightOff(elem, id)
{
var target = document.getElementById(id);
if(elem.cacheClassElem)
elem.className = elem.cacheClassElem;
if(elem.cacheClassTarget)
target.className = elem.cacheClassTarget;
}
</script>
</head>
<body>
<div id="content">
<header>
<h1 class="title" id="toc-titre">Gestion des processus Unix</h1>
</header>
<nav id="table-of-contents"><ul><li class="toc-h1 toc-active visited_after_load"><a href="#toc-titre">Gestion des processus Unix</a></li><li class="toc-h2"><a href="#titre-0">Unix : concepts fondamentaux</a></li><li class="toc-h2"><a href="#titre-1">1 Etape 1 : Les Processus</a></li><li class="toc-h3"><a href="#titre1-1">1.1 Identification : getpid() et getppid()</a></li><li class="toc-h3"><a href="#titre1-2">1.2 La primitive sleep()</a></li><li class="toc-h3"><a href="#titre1-3">1.3 La primitive exit()</a></li><li class="toc-h3"><a href="#titre1-4">1.4 Création d'un processus : fork()</a></li><li class="toc-h3"><a href="#titre1-5">1.5 Importance du exit()</a></li><li class="toc-h3"><a href="#titre1-6">1.6 Héritage des données</a></li><li class="toc-h3"><a href="#titre1-7">1.7 Héritage des descripteurs</a></li><li class="toc-h3"><a href="#titre1-8">1.8 Fils orphelin</a></li><li class="toc-h3"><a href="#titre1-9">1.9 Fils zombie</a></li><li class="toc-h3"><a href="#titre1-10">1.10 wait()</a></li><li class="toc-h3"><a href="#titre1-11">1.11 execl()</a></li><li class="toc-h3"><a href="#titre1-12">1.12 execv()</a></li><li class="toc-h3"><a href="#titre1-13">1.13 Conservation des descripteurs</a></li></ul></nav>
<div id="outline-container-0" class="outline-1">
<div class="org-center">
<font style="--darkreader-inline-color:#6b4de1;" data-darkreader-inline-color="" color="#4020C0">
Auteur: Zouheir HAMROUNI
</font>
</div>
<div id="outline-container-0" class="outline-2">
<h2 id="titre-0"><span class="section-number-2"></span>Unix : concepts fondamentaux</h2>
<div class="outline-text-2" id="text-0">
<p>
Unix met en oeuvre plusieurs concepts fondamentaux :
</p><ul>
<li>
Les processus : pour la gestion des traitements (exécutions de programmes).
Ce concept encapsule lexécution dun programme de façon à assurer lallocation et le contrôle
des ressources nécessaires à cette exécution (processeur(s), mémoires,
périphériques, fichiers, pipes, sockets…). Plusieurs processus peuvent
exister en parallèle et se partager de façon optimisée ces ressources.
</li>
<br>
<li>Les fichiers : pour la gestion des données, ce concept permet dassurer une rémanence et
un contrôle des données des usagers du système.
</li>
<br>
<li>
La gestion dynamique des processus et fichiers dans une structure
arborescente. En effet, tout processus est un descendant dun processus
père, et appartient à une arborescence qui a pour racine le processus
initial (numéro 1) ; et tout fichier est placé dans une arborescence de
répertoires ayant une racine unique.
</li>
<br>
<li>La protection des ressources : Tout processus sexécute pour un usager appartenant à un groupe.
Tout fichier possède de la même manière un créateur identifié. Lidentification dun usager
définit ainsi une capacité daccès de cet usager aux ressources du système via les processus
quil engendrera.
</li>
<br>
<li>
La transparence de larchitecture matérielle : ce principe consiste à masquer
les particularités des architectures supports. Le noyau système définit par exemple un système
de gestion dexceptions (déroutements et interruptions), et des signaux indépendants de tout
processeur matériel.
</li>
</ul>
</div>
</div>
<div id="outline-container-1" class="outline-2">
<h2 id="titre-1"><span class="section-number-2">1 </span>Etape 1 : Les Processus</h2>
Un processus est une instance d'exécution d'un programme (un programme
en cours d'exécution). Ce concept encapsule lexécution dun programme
de manière à assurer lallocation et le contrôle
des ressources nécessaires à cette exécution (temps processeur, mémoire,
périphériques, fichiers, pipes, sockets…). Plusieurs processus peuvent
exister en parallèle et se partager de façon optimisée ces ressources.
<p>
Les processus sont organisés dans une structure arborescente : tout
processus est un descendant dun processus père, et appartient à une
arborescence qui a pour racine le processus initial.
</p><p>
Chaque processus Unix possède un numéro "pid" (process id), et un
processus père (son créateur, et son supérieur dans l'arborescence des
processus). Le processus initial (racine de l'arborescence) porte le
numéro 1.
</p><p>
Nous allons nous intéresser aux primitives de base de gestion des
processus. Par défaut, et sauf précision contraire, ces primitives sont
définies dans "unistd.h", fichier à référencer en début du code.
</p><pre><font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#include</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;</font>unistd.h<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&gt;</font>
</pre>
<div id="outline-container-1-1" class="outline-3">
<h3 id="titre1-1"><span class="section-number-3">1.1 </span>Identification : getpid() et getppid()</h3>
<div class="outline-text-3" id="text-1-1">
<ul>
<li>
<methode>pid_t getpid()</methode> : retourne le pid du processus appelant (pid_t : synonyme d'entier).
</li>
<li>
<methode>pid_t getppid()</methode> : retourne le pid du père du processus appelant.
</li>
</ul>
<p>Chaque processus peut donc connaître son numéro (pid) et le numéro de son père (ppid).
</p></div>
</div>
<div id="outline-container-1-2" class="outline-3">
<h3 id="titre1-2"><span class="section-number-3">1.2 </span>La primitive sleep()</h3>
<div class="outline-text-3" id="text-1-2">
<methode>unsigned int sleep(int n)</methode> : endort le processus
appelant pour une durée de n secondes. Cette durée peut être écourtée
dès qu'un signal non ignoré est reçu.
<p>
<methode>sleep()</methode> renvoie zéro si le temps prévu s'est écoulé, ou le nombre de secondes restantes si l'appel a été interrompu.
</p><p>
Nous l'utiliserons pour faire durer les processus testés pendant un temps choisi.
</p></div>
</div>
<div id="outline-container-1-3" class="outline-3">
<h3 id="titre1-3"><span class="section-number-3">1.3 </span>La primitive exit()</h3>
<div class="outline-text-3" id="text-1-3">
<methode>void exit(int n)</methode> : met fin au processus appelant avec n comme code de retour.
<p>Par convention, le code de retour est :
</p><ul>
<li>
est égal à 0 (EXIT_SUCCESS : constante prédéfinie) après un comportement correct
</li>
<li>
est différent de 0 pour indiquer une erreur
</li>
</ul>
</div>
</div>
<div id="outline-container-1-4" class="outline-3">
<h3 id="titre1-4"><span class="section-number-3">1.4 </span>Création d'un processus : fork()</h3>
<div class="outline-text-3" id="text-1-4">
Un processus peut créer un fils en appelant la primitive fork() :
<p>
<methode>pid_t fork()</methode> : crée dynamiquement un nouveau processus (fils) qui s'exécute de façon
concurrente avec le processus qui le crée (processus père). Ce processus fils hérite du processus
père les attributs suivants :
</p><ul>
<li>
même code
</li>
<li>
une copie de la zone de données du père
</li>
<li>
environnement d'exécution
</li>
<li>
priorité
</li>
<li>
descripteurs de fichiers ouverts
</li>
<li>
traitement des signaux
</li>
</ul>
Après exécution du <methode>fork()</methode>, on se trouve avec deux processus (un père et un fils)
ayant le même code et
la même image de données. En cas de succès, la primitive <methode>fork()</methode> renvoie deux valeurs différentes :
<ul>
<li>
dans le code du père : la valeur de retour indique le pid du fils créé (&gt;0)
</li>
<li>
dans le code du fils : la valeur de retour est égale à 0
</li>
</ul>
En cas d'échec (nombre maximum de processus atteint) : aucun fils n'est créé et la valeur de retour du <methode>fork()</methode> est égale à -1
<p>Même si le père et son fils ont le même code, on peut différencier les traitements effectués
par l'un et par l'autre en se basant sur la valeur de retour du fork.
</p><p>
Le code suivant illustre ce concept : le processus principal crée 3 fils, en
répétant le même traitement à l'intérieur d'une boucle "for" dans laquelle il passe 3 fois.
</p><p>
Au premier passage (fils=1), le processus principal exécute la primitive <methode>fork()</methode>,
dont on doit traiter les 3 cas de retour :
</p><ul>
<li>
retour = -1 : le <methode>fork()</methode> a échoué et aucun fils n'a été créé. Dans ce cas, le processus principal s'arrête en faisant appel à la primitive <methode>exit()</methode> et en y indiquant une valeur d'arrêt différente de 0 (par convention). Il est important
de prévoir le traitement du retour d'erreur de toute primitive système.
</li>
<br>
<li>
retour &gt;= 0 : le <methode>fork()</methode> a créé un processus fils qui hérite du même code que son père. La valeur de retour n'est pas la même dans les deux codes :
</li>
<br>
<ul>
<li>
retour = 0 : on se trouve dans le code du fils, qui va exécuter la séquence à l'intérieur du
"if (retour == 0)" :
</li>
<ul>
<li>
affiche son numéro, son pid et le pid de son père
</li>
<li>
s'endort pendant 3 secondes
</li>
<li>
et s'arrête en faisant appel à la primitive <methode>exit()</methode>. Par conséquent, le fils,
même s'il hérite de la
totalité du code de son père, ne va jamais entrer de nouveau dans la boucle "for".
Nous verrons plus loin ce qu'il se passe si on enlève l'appel à <methode>exit()</methode>.
</li>
</ul>
<p>
</p><li>
retour &gt; 0 : on se trouve dans le code du père, qui affiche le numéro et le pid du fils qu'il vient
de créer, et repart dans la boucle "for".
</li>
</ul>
</ul>
Le même traitement se répète lors du deuxième et du troisième passage dans la boucle "for".
<p>
</p><pre> 1 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Exemple d'illustration des primitives Unix : Un père et ses fils */</font>
2 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Création de fils : fork et exit */</font>
3
4 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#include</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;</font>stdio.h<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&gt;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* entrées sorties */</font>
5 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#include</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;</font>unistd.h<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&gt;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* pimitives de base : fork, ...*/</font>
6 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#include</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;</font>stdlib.h<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&gt;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* exit */</font>
7
8 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#define</font> NB_FILS 3 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* nombre de fils */</font>
9
10 <font style="--darkreader-inline-color:#ff72ff;" data-darkreader-inline-color="" color="purple">int</font> main<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font>
11 {
12 <font style="--darkreader-inline-color:#ff72ff;" data-darkreader-inline-color="" color="purple">int</font> fils, retour <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
13 <font style="--darkreader-inline-color:#ff72ff;" data-darkreader-inline-color="" color="purple">int</font> duree_sommeil <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> 2 <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
14
15 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"\nJe suis le processus principal de pid %d\n"</font>, getpid<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
16
17 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">for</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>fils <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> 1 <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> fils <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;=</font> NB_FILS <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> fils++<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> {
18 retour <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> fork<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
19
20 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Bonne pratique : tester systématiquement le retour des appels système */</font>
21 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">if</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>retour <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;</font> 0<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> { <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* échec du fork */</font>
22 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"Erreur fork\n"</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
23 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Convention : s'arrêter avec une valeur <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&gt;</font> 0 en cas d'erreur */</font>
24 exit<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>1<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
25 }
26
27 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* fils */</font>
28 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">if</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>retour <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">==</font> 0<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> {
29 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"\n Processus fils numero %d, de pid %d, de pere %d.\n"</font>,
30 fils, getpid<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font>, getppid<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
31 sleep<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>duree_sommeil<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
32 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Important : terminer un processus par exit */</font>
33 exit<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>EXIT_SUCCESS<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Terminaison normale <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>0 <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> sans erreur<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> */</font>
34 }
35
36 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* pere */</font>
37 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">else</font> {
38 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"\nProcessus de pid %d a cree un fils numero %d, de pid %d \n"</font>,
39 getpid<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font>, fils, retour<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
40 }
41 }
42 sleep<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>duree_sommeil<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
43 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">return</font> <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">EXIT_SUCCESS</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
44 }
</pre>
<p>Pour valider cet exercice, il faut :
</p><ul>
<li>
Compiler le code ci-dessus : gcc -Wall -o nom_executable pere_fils.c
</li>
<li>
lancer l'outil de validation "apisys" dans un terminal shell
</li>
<li>
se placer sur le bon exercice (commandes p et s) et lancer son exécution
</li>
<li>
répondre aux questions posées
</li>
</ul>
<h4 class="trigger"> <a href="#">Visualiser l'interprétation des résultats</a></h4>
<section class="toggle_container" style="display: none;">
<p>
En exécutant ce code, on peut voir 7 messages affichés à l'écran :
</p><ul>
<li>
4 messages affichés par le père : 1 avant la boucle "for", et 1 à chaque passage dans la boucle "for"
</li>
<li>
1 message affiché par chaque fils
</li>
</ul>
En répétant l'exécution plusiuers fois, on peut remarquer que ces 7 messages ne
s'affichent pas toujours dans le même ordre. Car l'ordonnancement des processus
n'est pas le même d'une exécution à l'autre.
<p>
En exécutant ce code, et en tapant rapidement la commande "ps l" dans un
autre termianl (avant l'expiration des 3 secondes), on peut vérifier
l'existante des 4 processus, et leurs liens de paranté (colonnes PID et
PPID).
</p></section>
</div>
</div>
<div id="outline-container-1-5" class="outline-3">
<h3 id="titre1-5"><span class="section-number-3">1.5 </span>Importance du <methode>exit()</methode></h3>
<div class="outline-text-3" id="text-1-5">
<p>Dans l'exemple dessus, le code du fils est délimité entre le "if (retour == 0)" et <methode>exit(EXIT_SUCCESS)</methode>. Ce qui permet de séparer clairement le code exécuté par le père de celui du fils.
</p><p>
Si on reprend le même code que dessus et on supprime le <methode>exit(EXIT_SUCCESS)</methode>, on abtient un comprtement très différent des fils.
</p><pre> 1 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Exemple d'illustration des primitives Unix : Un père et ses fils */</font>
2 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Absence du exit dans le fils, et conséquences */</font>
3
4 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#include</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;</font>stdio.h<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&gt;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* entrées sorties */</font>
5 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#include</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;</font>unistd.h<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&gt;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* pimitives de base : fork, ...*/</font>
6 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#include</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;</font>stdlib.h<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&gt;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* exit */</font>
7
8 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#define</font> NB_FILS 3 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* nombre de fils */</font>
9
10 <font style="--darkreader-inline-color:#ff72ff;" data-darkreader-inline-color="" color="purple">int</font> main<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font>
11 {
12 <font style="--darkreader-inline-color:#ff72ff;" data-darkreader-inline-color="" color="purple">int</font> fils, retour <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
13 <font style="--darkreader-inline-color:#ff72ff;" data-darkreader-inline-color="" color="purple">int</font> duree_sommeil <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> 3 <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
14
15 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"\nJe suis le processus principal de pid %d\n"</font>, getpid<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
16
17 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">for</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>fils <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> 1 <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> fils <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;=</font> NB_FILS <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> fils++<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> {
18 retour <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> fork<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
19
20 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Bonne pratique : tester systématiquement le retour des appels système */</font>
21 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">if</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>retour <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;</font> 0<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> {
22 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"Erreur fork\n"</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
23 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Convention : s'arrêter avec une valeur <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&gt;</font> 0 en cas d'erreur */</font>
24 exit<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>1<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
25 }
26
27 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* fils */</font>
28 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">if</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>retour <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">==</font> 0<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> {
29 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"\n Processus fils numero %d, de pid %d, de pere %d.\n"</font>,
30 fils, getpid<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font>, getppid<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
31 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Le fils ne s'arrete pas ici */</font>
32 }
33
34 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* pere */</font>
35 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">else</font> {
36 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"\nProcessus de pid %d a cree un fils numero %d, de pid %d \n"</font>,
37 getpid<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font>, fils, retour<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
38 }
39 }
40 sleep<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>duree_sommeil<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
41 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">return</font> <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">EXIT_SUCCESS</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
42 }
</pre>
<p>
Testez ce code dans l'outil "apisys" (comme indiqué plus haut), et répondez aux questions posées.
</p><h4 class="trigger"> <a href="#">Visualiser l'interprétation des résultats</a></h4>
<section class="toggle_container" style="display: none;">
<p>
</p><p>A l'exécution de ce code, on obtient le comportement suivant :
</p><ul>
<li>
lors du premier passage dans la boucle, le processus principal (père) crée un premier fils (que l'on appellera fils_1),
qui continue à exécuter le code de la boucle "for", car il n'y a plus d'exit qui l'arrête :
donc deux processus qui vont exécuter le deuxième passage de laboucle "for"
</li>
<p>
</p><li>
lors du dexième passage dans la boucle (père et fils_1) :
<ul>
<li>
le processus père crée un dexième fils (fils_2)
</li>
<li>
le porcessus fils_1 crée un fils que l'on nommera petit_fils_1_1
</li>
</ul>
</li>
</ul>
<ul>
<li>
lors du troisième passage dans la boucle (père, fils_1, fils_2 et petit_fils_1_1) :
<ul>
<li>
le processus père crée un troisième fils (fils_3)
</li>
<li>
le porcessus fils_1 crée un deuxième fils que l'on nommera petit_fils_1_2
</li>
<li>
le porcessus fils_2 crée un fils que l'on nommera petit_fils_2_1
</li>
<li>
le porcessus petit_fils_1_1 crée un fils que l'on nommera arrière_petit_fils_1_1
</li>
</ul>
</li>
<p>
</p><li>
Et s'il y avait un éventuel quatrième passage, 8 nouveaux processus seraient créés,
donc doublement du nombre de processus à chaque nouveau passge dans la boucle !
</li></ul>
</section>
</div>
</div>
<div id="outline-container-1-6" class="outline-3">
<h3 id="titre1-6"><span class="section-number-3">1.6 </span>Héritage des données</h3>
<div class="outline-text-3" id="text-1-6">
Comme indiqué dessus, le processus fils hérite d'une copie de la zone de données de son père.
Il possède donc une copie de toutes les variables du code. Pour une variable donnée,
la valeur vue par le fils est la même que celle vue par le père tant que cette variable
n'est pas modifiée. Car dès que la avriable est modifiée par le père ou par le fils,
la copie du fils devient forcément différente de celle du père.
<p>
Le code suivant reprend le premier code présenté plus haut en ajoutant une variable appelée "patrimoine_fils",
que le père initialise à 10000, comme cadeau de naissance qu'il réserve à chaque nouveau fils.
</p><p>
Chaque fils, fait fructifier son patrimoine, modifie donc la variable patrimoine_fils, et l'affiche avant de s'arrêter.
</p><p>
De son côté, le père essaie de calculer le patrimoine total de ses fils en lisant la variable
patrimoine_fils, mais malheureusement pour lui, il n'a accès qu'à sa propore copie, et pas
à celles de ses fils.
</p><pre> 1 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Exemple d'illustration des primitives Unix : Un père et ses fils */</font>
2 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Héritage et dupplication des données */</font>
3
4 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#include</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;</font>stdio.h<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&gt;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* entrées sorties */</font>
5 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#include</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;</font>unistd.h<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&gt;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* pimitives de base : fork, ...*/</font>
6 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#include</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;</font>stdlib.h<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&gt;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* exit */</font>
7
8 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#define</font> NB_FILS 3 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* nombre de fils */</font>
9 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#define</font> DELAI 3
10
11 <font style="--darkreader-inline-color:#ff72ff;" data-darkreader-inline-color="" color="purple">int</font> main<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font>
12 {
13 <font style="--darkreader-inline-color:#ff72ff;" data-darkreader-inline-color="" color="purple">int</font> fils, retour <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
14 <font style="--darkreader-inline-color:#ff72ff;" data-darkreader-inline-color="" color="purple">int</font> cagnotte, patrimoine_fils <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
15 <font style="--darkreader-inline-color:#ff72ff;" data-darkreader-inline-color="" color="purple">int</font> duree_sommeil <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> 3 <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
16 cagnotte <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> 30000 <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
17 patrimoine_fils <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> cagnotte / NB_FILS <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
18
19 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"\nJe suis le processus principal de pid %d\n"</font>, getpid<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
20 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"Je dispose de %d Euros, que je partage entre mes futurs fils\n"</font>, cagnotte<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
21
22 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">for</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>fils <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> 1 <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> fils <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;=</font> NB_FILS <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> fils++<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> {
23 retour <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> fork<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
24
25 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Bonne pratique : tester systématiquement le retour des appels système */</font>
26 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">if</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>retour <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;</font> 0<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> { <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* échec du fork */</font>
27 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"Erreur fork\n"</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
28 exit<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>1<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
29 }
30
31 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* fils */</font>
32 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">if</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>retour <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">==</font> 0<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> {
33 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"\n Processus fils numero %d : mon pere m'a offert %d Euros\n"</font>,
34 fils, patrimoine_fils<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
35 patrimoine_fils <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> patrimoine_fils * <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>fils + 1<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
36 sleep<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>duree_sommeil<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
37 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"\n Processus fils numero %d - j'ai augmente mon patrimoine a %d Euros\n"</font>,
38 fils, patrimoine_fils<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
39 exit<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>EXIT_SUCCESS<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Te:rminaison normale <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>0 <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> sans erreur<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> */</font>
40 }
41
42 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* pere */</font>
43 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">else</font> {
44 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"\nProcessus de pid %d a cree un fils numero %d, de pid %d \n"</font>,
45 getpid<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font>, fils, retour<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
46 }
47 }
48 sleep<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>duree_sommeil+1<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
49
50 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"\nProcessus Principal - le patrimoine total de mes fils est de %d\n"</font>, patrimoine_fils*NB_FILS<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
51 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">return</font> <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">EXIT_SUCCESS</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
52 }
</pre>
<p>
Testez ce code dans l'outil "apisys" (comme indiqué plus haut), et répondez aux questions posées.
</p><h4 class="trigger"> <a href="#">Visualiser l'interprétation des résultats</a></h4>
<section class="toggle_container" style="display: none;">
<p>A l'exécution de ce code, on vérifie bien que la variable
patrimoine_fils n'a plus la même valeur dans le père et dans les fils,
dès qu'elle est modifiée par l'un ou par l'autre. Le père conserve sa
copie initiale et n'a
aucun accès aux copies modifiées par ses fils.
</p></section>
</div>
</div>
<div id="outline-container-1-7" class="outline-3">
<h3 id="titre1-7"><span class="section-number-3">1.7 </span>Héritage des descripteurs</h3>
<div class="outline-text-3" id="text-1-7">
<p>
Chaque processus échange des informations avec son environnement (écran, clavier,
fichiers, etc) sous la forme de suites doctets (ou flots dentrées/sorties).
L'accès à chaque canal de communication (lecture/écriture) se fait par l'intermédiaire d'un descripteur (numéro &gt;=0).
</p>
<p>
Par défaut, Unix/Linux gère trois flots dentrée/sortie :
</p><ul>
<li>
lentrée standard (flot numéro 0), <code>stdin</code>, associée au clavier,
</li>
<li>
la sortie standard (flot numéro 1), <code>stdout</code>, associée à lécran,
</li>
<li>
la sortie erreur standard (flot numéro 2), <code>stderr</code>, associée aussi à lécran.
</li>
</ul>
<div class="encadreblanc">
Il est possible de modifier ces associations pour un processus : par exemple, associer la sortie
standad à un fichier, de manère à ce que les messages ne s'affichent plus à l'écran,
mais s'écrivent dans ce fichier.
<p>Cette modification ne nécessite pas la modification du code,
et se fait simplement avec un mécanisme appelé redirection :
</p><ul>
<li>
la sortie standard peut être redéfinie à laide du caractère <code>&gt;</code> : dans la commande
suivante, le résultat du <code>ls</code> est redirigé dans le fichier <i>fic</i>
<pre><code>ls &gt;</code> <i>fic</i>
</pre>
</li>
<li>
il est possible d'ajouter à un fichier le résultat d'une commande : dans la commande suivante,
le résultat du <code>ls -l</code> s'ajoute au fichier <i>fic</i>
<pre><code>ls -l &gt;&gt;</code> <i>fic</i>
</pre>
</li>
<li>
en Bourne shell, sh ou bash, la sortie erreur standard peut être redirigée par
<code>2&gt;</code> : la commande suivante écrit les messages derreurs éventuellement
engendrés par lexécution de <code>rm</code> dans le fichier <i>fic</i>
<pre><code>rm toto 2&gt;</code> <i>ficerreur</i>
</pre>
</li>
<li>
lentrée standard peut être redirigée par <code>&lt;</code> : les commandes suivantes
réalisent une lecture d'un caractère au clavier et son affichage, en passant par la variable c
<pre><code>read c; echo $c </code>
</pre>
Dans cette seconde version, la lecture est faite dans le fichier <i>fic</i>
<pre><code>read c &lt;</code> <i>fic</i> <code>; echo $c </code>
</pre>
</li>
</ul>
</div>
<p>Un processus fils hérite de tous les descripteurs ouverts dans son père (entrées/sorties
standard, fichiers, etc.).
</p><ul>
<li>
Nous avons vu lors des exécutions précédentes que les messages
du père et ceux des différents fils sont affichés dans le même terminal (sortie standard).
</li>
<p>
</p><li>
De même, tout descripteur de fichier ouvert par le père est hérité par ses fils,
y compris lorsque ce fichier est ouvert par redirection.
</li>
</ul>
<p>
Pour illustrer cela, on reprend le premier programme pere_fils.c et on l'exécute en redirigeant
la sortie standard dans un fichier : (pere_fils &gt; fic_sortie).
</p><p>Après exécution, on peut remarquer :
</p><ul>
<li>
aucun message n'est affiché dans le terminal d'exécution
</li>
<li>
les messages qui devaient s'afficher dans le terminal d'exécution se trouvent
maintenant dans le fichier "fic_sortie"
</li>
<li>
mais, certains messages sont en double ou en triple
</li>
</ul>
<p>L'explication de ce dernier point, se trouve dans le fonctionnement du "printf".
D'après le standard ISO, le comprtement du "printf" n'est pas le même pour la sortie
standard et pour un fichier ordinaire :
</p><ul>
<li>
dans le cas d'une sortie interactive (terminal), le flot est géré par ligne
et \n provoque la vidange du tampon langage
</li>
<li>
dans le cas d'une sortie dans un fichier ordinaire, le flot est géré par
bloc
(pour limiter les échanges avec le fichier) : '\n' est traité comme un
caractère ordinaire et ne commande plus la vidange du buffer.
</li>
</ul>
<p>
Chaque fils hérite du tampon (zone mémoire) de sortie du père, qui contient les messages
déjà envoyés par le père et non vidangés, auxquels va s'ajouter le message du fils.
Par conséquent, chaque fils va envoyer un flot de données contenant, en plus de son propre
message, les messages antérieurs du père. C'est pour cela que certains messages se
strouvent en 3 exemplaires (réaffichés par les fils 2 et 3), et d'autres en double
exemplaire (réaffichés par le fils 3).
</p><ul>
<li>
Le fis nuéro 1 récupère un tampon qui contient le premeir message du père
</li>
<li>
Le fis nuéro 2 récupère un tampon qui contient
<ul>
<li>
le premeir message du père
</li>
<li>
le message affiché par le père lors du premier passage dans la boucle
</li>
</ul>
</li>
<li>
Le fis nuéro 3 récupère un tampon qui contient
<ul>
<li>
le premeir message du père
</li>
<li>
le message affiché par le père lors du premier passage dans la boucle
</li>
<li>
le message affiché par le père lors du deuxième passage dans la boucle
</li>
</ul>
</li>
</ul>
<p>
Pour forcer la vidange du tampon de sortie, on fait un appel explicite à <methode>fflush(stdout)</methode> après
chaque printf du père. Ainsi, le fils créé hérite d'un tampon vide et ne dupplique plus
l'affichage des messages de son père.
</p><pre> 1 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Exemple d'illustration des primitives Unix : Un père et ses fils */</font>
2 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Redirection et fflush */</font>
3
4 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#include</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;</font>stdio.h<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&gt;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* entrées sorties */</font>
5 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#include</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;</font>unistd.h<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&gt;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* pimitives de base : fork, ...*/</font>
6 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#include</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;</font>stdlib.h<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&gt;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* exit */</font>
7
8 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#define</font> NB_FILS 3 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* nombre de fils */</font>
9
10 <font style="--darkreader-inline-color:#ff72ff;" data-darkreader-inline-color="" color="purple">int</font> main<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font>
11 {
12 <font style="--darkreader-inline-color:#ff72ff;" data-darkreader-inline-color="" color="purple">int</font> fils, retour <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
13 <font style="--darkreader-inline-color:#ff72ff;" data-darkreader-inline-color="" color="purple">int</font> duree_sommeil <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> 2 <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
14
15 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"\nJe suis le processus principal de pid %d\n"</font>, getpid<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
16
17 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Vidange du tampon de sortie pour que le fils le récupère vide */</font>
18 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* D'après le standard ISO le comportement du printf présente 2 cas : */</font>
19 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* - sortie interactive <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>terminal<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> : flot géré par ligne et \n provoque */</font>
20 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* la vidange du tampon langage </font>
21 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* - sortie dans un fichier : flot géré par bloc et \n est traité comme */</font>
22 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* un caractère ordinaire. fflush<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>stdout<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> force la vidange du tampon. */</font>
23
24 fflush<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>stdout<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
25
26 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">for</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>fils <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> 1 <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> fils <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;=</font> NB_FILS <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> fils++<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> {
27 retour <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> fork<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
28
29 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Bonne pratique : tester systématiquement le retour des appels système */</font>
30 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">if</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>retour <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;</font> 0<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> { <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* échec du fork */</font>
31 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"Erreur fork\n"</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
32 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Convention : s'arrêter avec une valeur <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&gt;</font> 0 en cas d'erreur */</font>
33 exit<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>1<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
34 }
35
36 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* fils */</font>
37 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">if</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>retour <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">==</font> 0<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> {
38 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"\n Processus fils numero %d, de pid %d, de pere %d.\n"</font>,
39 fils, getpid<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font>, getppid<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
40 sleep<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>duree_sommeil<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
41 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Important : terminer un processus par exit */</font>
42 exit<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>EXIT_SUCCESS<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Terminaison normale <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>0 <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> sans erreur<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> */</font>
43 }
44
45 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* pere */</font>
46 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">else</font> {
47 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"\nProcessus de pid %d a cree un fils numero %d, de pid %d \n"</font>,
48 getpid<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font>, fils, retour<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
49 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* vidange du tampon de sortie pour que le fils le récupère vide */</font>
50 fflush<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>stdout<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
51 }
52 }
53 sleep<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>duree_sommeil<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
54 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">return</font> <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">EXIT_SUCCESS</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
55 }
</pre>
</div>
</div>
<p>Testez ce code dans l'outil "apisys" et vérifiez que les messages ne sont
plus duppliqués.
</p><div id="outline-container-1-8" class="outline-3">
<h3 id="titre1-8"><span class="section-number-3">1.8 </span>Fils orphelin</h3>
<div class="outline-text-3" id="text-1-8">
<p>
Lorsque le processus père se termine (disparait) avant son fils, ce dernier devient orphelin,
et est rattaché (adopté) au processus initial portant le numéro 1.
</p>
<p>
On reprend le programme initial pere_fils.c, et on fait durer les fils plus
longtemps que le père, en agissant sur le paramètre du sleep.
</p><pre> 1 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Exemple d'illustration des primitives Unix : Un père et ses fils */</font>
2 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Fils orphelins */</font>
3
4 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#include</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;</font>stdio.h<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&gt;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* entrées sorties */</font>
5 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#include</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;</font>unistd.h<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&gt;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* pimitives de base : fork, ...*/</font>
6 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#include</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;</font>stdlib.h<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&gt;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* exit */</font>
7
8 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#define</font> NB_FILS 3 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* nombre de fils */</font>
9
10 <font style="--darkreader-inline-color:#ff72ff;" data-darkreader-inline-color="" color="purple">int</font> main<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font>
11 {
12 <font style="--darkreader-inline-color:#ff72ff;" data-darkreader-inline-color="" color="purple">int</font> fils, retour <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
13 <font style="--darkreader-inline-color:#ff72ff;" data-darkreader-inline-color="" color="purple">int</font> duree_sommeil <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> 120 <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
14
15 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"\nJe suis le processus principal de pid %d\n"</font>, getpid<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
16
17 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">for</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>fils <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> 1 <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> fils <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;=</font> NB_FILS <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> fils++<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> {
18 retour <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> fork<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
19
20 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Bonne pratique : tester systématiquement le retour des appels système */</font>
21 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">if</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>retour <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;</font> 0<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> { <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* échec du fork */</font>
22 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"Erreur fork\n"</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
23 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Convention : s'arrêter avec une valeur <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&gt;</font> 0 en cas d'erreur */</font>
24 exit<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>1<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
25 }
26
27 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* fils */</font>
28 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">if</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>retour <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">==</font> 0<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> {
29 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"\n Processus fils numero %d, de pid %d, de pere %d.\n"</font>,
30 fils, getpid<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font>, getppid<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
31 sleep<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>duree_sommeil<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
32 exit<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>EXIT_SUCCESS<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Terminaison normale */</font>
33 }
34
35 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* pere */</font>
36 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">else</font> {
37 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"\nProcessus de pid %d a cree un fils numero %d, de pid %d \n"</font>,
38 getpid<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font>, fils, retour<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
39 }
40 }
41 sleep<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>1<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
42 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">return</font> <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">EXIT_SUCCESS</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
43 }
</pre>
<p>
Si on exécute ce nouveau code, et on tape
la commande "ps l" dans un autre terminal, on peut voir dans la colonne "PPID"
du tableau affiché, que les 3 fils ont pour père le processus 1.
</p></div>
</div>
<div id="outline-container-1-9" class="outline-3">
<h3 id="titre1-9"><span class="section-number-3">1.9 </span>Fils zombie</h3>
<div class="outline-text-3" id="text-1-9">
<p>
Lorsque un processus fils se termine sans que son père prenne connaissance de cette
terminaison, ce fils reste présent et entre dans un état zombie.
</p>
<p>
On reprend le programme initial pere_fils.c, et on fait durer le père plus
longtemps que les fils, en agissant sur le paramètre du sleep.
</p><pre> 1 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Exemple d'illustration des primitives Unix : Un père et ses fils */</font>
2 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Fils Zombie */</font>
3
4 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#include</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;</font>stdio.h<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&gt;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* entrées sorties */</font>
5 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#include</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;</font>unistd.h<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&gt;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* pimitives de base : fork, ...*/</font>
6 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#include</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;</font>stdlib.h<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&gt;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* exit */</font>
7
8 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#define</font> NB_FILS 3 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* nombre de fils */</font>
9
10 <font style="--darkreader-inline-color:#ff72ff;" data-darkreader-inline-color="" color="purple">int</font> main<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font>
11 {
12 <font style="--darkreader-inline-color:#ff72ff;" data-darkreader-inline-color="" color="purple">int</font> fils, retour <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
13 <font style="--darkreader-inline-color:#ff72ff;" data-darkreader-inline-color="" color="purple">int</font> duree_sommeil <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> 120 <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
14
15 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"\nJe suis le processus principal de pid %d\n"</font>, getpid<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
16
17 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">for</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>fils <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> 1 <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> fils <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;=</font> NB_FILS <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> fils++<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> {
18 retour <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> fork<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
19
20 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Bonne pratique : tester systématiquement le retour des appels système */</font>
21 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">if</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>retour <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;</font> 0<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> { <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* échec du fork */</font>
22 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"Erreur fork\n"</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
23 exit<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>1<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
24 }
25
26 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* fils */</font>
27 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">if</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>retour <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">==</font> 0<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> {
28 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"\n Processus fils numero %d, de pid %d, de pere %d.\n"</font>,
29 fils, getpid<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font>, getppid<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
30 exit<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>EXIT_SUCCESS<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Terminaison normale */</font>
31 }
32
33 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* pere */</font>
34 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">else</font> {
35 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"\nProcessus de pid %d a cree un fils numero %d, de pid %d \n"</font>,
36 getpid<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font>, fils, retour<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
37 }
38 }
39 sleep<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>duree_sommeil<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
40 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">return</font> <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">EXIT_SUCCESS</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
41 }
</pre>
<p>
Si on exécute ce nouveau code, et on tape
la commande "ps l" dans un autre terminal, on peut voir dans la colonne STAT
du tableau affiché, que les 3 fils sont dans l'état zombie (Z, ou Z+) et dans la
dernière colonne le terme "defunct" ajouté après leur nom.
</p></div>
</div>
<div id="outline-container-1-10" class="outline-3">
<h3 id="titre1-10"><span class="section-number-3">1.10 </span>wait()</h3>
<div class="outline-text-3" id="text-1-10">
Souvent, le processus père a besoin de prendre connaissance de la terminaison
des fils qu'il a créés, et d'en connaître le code ou la cause de fin. La primitive
<methode>wait()</methode> (définie dans sys/wait.h) permet de réaliser
cette opération.
<p>
<methode>pid_t wait(int *status)</methode> permet d'attendre (de façon bloquante) la terminaison
d'un fils du processus appelant (terminé avec exit ou tué par un signal). Elle :
</p><ul>
<li> renvoie le pid du fils qui s'est arrêté ou a été arrêté
</li>
<p>
</p><li> indique dans le paramètre status, passé par référence, le code de terminaison (exit)
ou le numéro du signal ayant tué le fils. L'accès à ces informations est facilité par des macros :
<ul>
<li>
WIFEXITED(status) est vrai si le fils s'est terminé avec exit
</li>
<li>WEXITSTATUS(status) renvoie la valeur du exit
</li>
<li>WIFSIGNALED(status) est vrai si le fils a été tué par un signal
</li>
<li>WTERMSIG(status) renvoie le numéro du signal ayant tué le fils
</li>
</ul>
</li>
</ul>
<p>Le code suivant reprend le code initial en y modifiant les points suivants :
</p><ul>
<li>les fils 1 et 3 terminent immédiatement sans attente
</li>
<li>le fils 2 s'en dort pendant une durée assez longue
</li>
<li>les 3 fils renvoient leur numéro (respectivement 1, 2, 3) comme valeur de fin
</li>
<li>le processus principal (père) attend la fin de ses 3 fils, et affiche pour chacun d'eux :
<ul>
<li>la cause de teminaison : avec exit, ou tué par un signal :
</li>
<li>la valuer du exit ou le numéro du signal
</li>
</ul>
</li>
</ul>
<pre> 1 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Exemple d'illustration des primitives Unix : Un père et ses fils */</font>
2 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* wait : le père attend la fin de ses fils */</font>
3
4 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#include</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;</font>stdio.h<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&gt;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* entrées sorties */</font>
5 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#include</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;</font>unistd.h<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&gt;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* pimitives de base : fork, ...*/</font>
6 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#include</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;</font>stdlib.h<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&gt;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* exit */</font>
7 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#include</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;</font>sys/wait.h<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&gt;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* wait */</font>
8
9 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#define</font> NB_FILS 3 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* nombre de fils */</font>
10
11 <font style="--darkreader-inline-color:#ff72ff;" data-darkreader-inline-color="" color="purple">int</font> main<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red"></font>
12 {
13 <font style="--darkreader-inline-color:#ff72ff;" data-darkreader-inline-color="" color="purple">int</font> fils, retour, wstatus, fils_termine <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
14 <font style="--darkreader-inline-color:#ff72ff;" data-darkreader-inline-color="" color="purple">int</font> duree_sommeil <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> 300<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
15
16 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"\nJe suis le processus principal de pid %d\n"</font>, getpid<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
17 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Vidange du tampon de sortie pour que le fils le récupère vide */</font>
18 fflush<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>stdout<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
19
20 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">for</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>fils <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> 1 <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> fils <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;=</font> NB_FILS <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> fils++<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> {
21 retour <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> fork<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
22
23 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Bonne pratique : tester systématiquement le retour des appels système */</font>
24 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">if</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>retour <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;</font> 0<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> { <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* échec du fork */
</font>
25 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"Erreur fork\n"</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
26 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Convention : s'arrêter avec une valeur <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&gt;</font> 0 en cas d'erreur */</font>
27 exit<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>1<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
28 }
29
30 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* fils */</font>
31 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">if</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>retour <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">==</font> 0<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> {
32 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"\n Processus fils numero %d, de pid %d, de pere %d.\n"</font>,
33 fils, getpid<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font>, getppid<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
34 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Le fils 2 s'endort pendant une durée asse longue */</font>
35 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">if</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>fils <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">==</font> 2<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> {
36 sleep<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>duree_sommeil<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
37 }
38 exit<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>fils<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* normalement exit<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>0<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font>, mais on veut illustrer WEXITSTATUS */</font>
39 }
40
41 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* pere */</font>
42 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">else</font> {
43 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"\nProcessus de pid %d a cree un fils numero %d, de pid %d \n"</font>,
44 getpid<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font>, fils, retour<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
45 }
46 }
47
48 sleep<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>3<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* pour les besoins de l'outil de validation automatique */</font>
49
50 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* attendre la fin des fils */</font>
51 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">for</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>fils <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> 1 <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> fils <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;=</font> NB_FILS <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> fils++<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> {
52 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* attendre la fin d'un fils */</font>
53 fils_termine <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> wait<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>&amp;wstatus<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
54
55 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">if</font> WIFEXITED<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>wstatus<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> { <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* fils terminé avec exit */
</font>
56 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"\nMon fils de pid %d a termine avec exit %d\n"</font>,
57 fils_termine, WEXITSTATUS<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>wstatus<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
58 }
59 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">else</font> <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">if</font> WIFSIGNALED<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>wstatus<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> { <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* fils tué par un signal */</font>
60 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"\nMon fils de pid %d a ete tue par le signal %d\n"</font>,
61 fils_termine, WTERMSIG<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>wstatus<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
62 }
63 }
64 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"\nProcessus Principal termine\n"</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
65 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">return</font> <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">EXIT_SUCCESS</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
66 }
</pre>
<p>Testez ce code dans l'outils "apisys" et répondez aux questions posées.
</p></div>
</div>
<div id="outline-container-1-11" class="outline-3">
<h3 id="titre1-11"><span class="section-number-3">1.11 </span>execl()</h3>
<div class="outline-text-3" id="text-1-11">
Les primitives <methode>exec</methode> constituent une famille de primitives permettant
le lancement de lexécution dun nouveau programme par le processus appelant.
Cela nentraîne pas la création dun nouveau processus mais seulement le chargement et
le lancement dun nouveau programme exécutable, en lieu et place du programme effectuant
lappel à la primitive <methode>exec</methode>.
<p>On parle de recouvrement :
le nouveau programme recouvre (remplace complètement) le processus appelant.
</p><p>
<methode>int execl(char *ref, char *arg0, char *arg1,..., char *argn, NULL)</methode>
</p><p>
</p><p>
<methode>int execlp(char *ref, char *arg0, char *arg1,..., char *argn, NULL)</methode>
</p><p>
permettent le lancement de lexécution du fichier exécutable dont :
</p><ul>
<li>
le nom est indiqué par le premier paramètre "ref"
</li>
<li>
la liste des arguments fournie dans "arg0", "arg1",…,"argn"
</li>
</ul>
<p>execlp effectue une recherche de l'exécutable dans tous les répertoires de PATH.
</p><p>
<methode>ref</methode> doit référencer un fichier qui existe et qui est exécutable.
Le paramètre "arg0" est obligatoire et pointe en général sur une chaîne
identique à celle pointée par "ref".
</p><p>
Le comportement de la primitive <methode>execl</methode> est le suivant :
</p><ul>
<li>
si l'exécutable référencé par <methode>ref</methode> existe, il sera chargé et lancé en
en lieu et place du processus courant, sans aucun retour dans ce dernier.
</li>
<li>
sinon, on continue à exécuter le code du processus appelant, et dans ce cas il faut traiter
l'erreur.
</li>
</ul>
<p>
On reprend l'exempe initial, et on :
</p><ul>
<li>
remplace dans les fils, l'appel à "sleep()" par l'exécution
du programme "dormir" qui fait la même chose.
</li>
<li>
introduit une petite erreur dans le nom de l'exécutable pour le fils 2
</li>
<li>
ajoute dans le père une boucle d'attente de la terminaison des 3 fils,
en affichant pour chacun le mode d'arrêt et la valeur correspondante
</li>
</ul>
Ce qui donne le code ci-dessous.
<p>
</p><pre> 1 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Exemple d'illustration des primitives Unix : Un père et ses fils */</font>
2 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* execl */</font>
3
4 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#include</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;</font>stdio.h<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&gt;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* entrées sorties */</font>
5 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#include</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;</font>unistd.h<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&gt;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* pimitives de base : fork, ...*/</font>
6 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#include</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;</font>stdlib.h<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&gt;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* exit */</font>
7 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#include</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;</font>sys/wait.h<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&gt;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* wait */</font>
8
9 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#define</font> NB_FILS 3 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* nombre de fils */</font>
10
11 <font style="--darkreader-inline-color:#ff72ff;" data-darkreader-inline-color="" color="purple">int</font> main<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font>
12 {
13 <font style="--darkreader-inline-color:#ff72ff;" data-darkreader-inline-color="" color="purple">int</font> fils, retour, wstatus, fils_termine <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
14
15 <font style="--darkreader-inline-color:#ff72ff;" data-darkreader-inline-color="" color="purple">char</font> ref_exec[]<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"./dormir"</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* exécutable */</font>
16 <font style="--darkreader-inline-color:#ff72ff;" data-darkreader-inline-color="" color="purple">char</font> arg0_exec[]<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"je dors"</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* argument0 du exec : nom donnée au processus */</font>
17 <font style="--darkreader-inline-color:#ff72ff;" data-darkreader-inline-color="" color="purple">char</font> arg1_exec[]<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"3"</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* argument0 du exec : durée de sommeil */</font>
18
19 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"Je suis le processus principal de pid %d\n"</font>, getpid<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
20 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Vidange du tampon de sortie pour que le fils le récupère vide */</font>
21 fflush<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>stdout<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
22
23 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">for</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>fils <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> 1 <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> fils <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;=</font> NB_FILS <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> fils++<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> {
24 retour <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> fork<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
25
26 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Bonne pratique : tester systématiquement le retour des appels système */</font>
27 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">if</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>retour <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;</font> 0<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> { <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* échec du fork */</font>
28 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"Erreur fork\n"</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
29 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Convention : s'arrêter avec une valeur <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&gt;</font> 0 en cas d'erreur */</font>
30 exit<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>1<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
31 }
32
33 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* fils */</font>
34 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">if</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>retour <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">==</font> 0<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> {
35
36 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* mettre un executable inexistant pour le fils 2 */</font>
37 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">if</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>fils <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">==</font> 2<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> {
38 ref_exec[3] <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> 'a' <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
39 }
40
41 execl<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>ref_exec, arg0_exec, arg1_exec, NULL<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
42
43 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* on ne se retrouve ici que si exec échoue */</font>
44 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"\n Processus fils numero %d : ERREUR EXEC\n"</font>, fils<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
45 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* perror : affiche un message relatif à l'erreur du dernier appel systàme */</font>
46 perror<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">" exec "</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
47 exit<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>fils<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* sortie avec le numéro di fils qui a échoué */ </font>
48 }
49 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* pere */</font>
50 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">else</font> {
51 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"\nProcessus de pid %d a cree un fils numero %d, de pid %d \n"</font>,
52 getpid<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font>, fils, retour<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
53 fflush<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>stdout<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
54 }
55 }
56 sleep<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>3<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* pour les besoins de l'outil de validation automatique */</font>
57
58 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* attendre la fin des fils */</font>
59 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">for</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>fils <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> 1 <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> fils <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;=</font> NB_FILS <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> fils++<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> {
60 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* attendre la fin d'un fils */</font>
61 fils_termine <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> wait<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>&amp;wstatus<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
62
63 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">if</font> WIFEXITED<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>wstatus<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> { <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* fils terminé avec exit */</font>
64 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"\nMon fils de pid %d a termine avec exit %d\n"</font>,
65 fils_termine, WEXITSTATUS<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>wstatus<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
66 }
67 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">else</font> <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">if</font> WIFSIGNALED<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>wstatus<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> { <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* fils tué par un signal */</font>
68 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"\nMon fils de pid %d a ete tue par le signal %d\n"</font>,
69 fils_termine, WTERMSIG<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>wstatus<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
70 }
71 }
72 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"\nProcessus Principal termine\n"</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
73 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">return</font> <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">EXIT_SUCCESS</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
74 }
</pre>
<p>
Testez ce code dans l'outil "apisys" (comme indiqué plus haut), et répondez aux questions posées.
</p><h4 class="trigger"> <a href="#">Visualiser l'interprétation des résultats</a></h4>
<section class="toggle_container" style="display: none;">
<p> En l'exécutant, on remarquera que pour les fils 1 et 3, les appels execl fonctionnent bien et
qu'il n'y a pas de retour après le exec :
</p><ul>
<li>pas d'exécution du printf("\n Processus fils numero %d : ERREUR EXEC\n", fils);
</li>
<li>pas d'exécution exit(fils) car la valeur de terminaison reçue pr le père est 0
(celle de dormir)
</li>
</ul>
Mais, pour le fils 2, le nom de l'exécutable n'était pas correct et le execl échoue.
Ce qui conduit au retour dans le code appelant le execl, et affichage des messages d'erreur.
</section>
</div>
</div>
<div id="outline-container-1-12" class="outline-3">
<h3 id="titre1-12"><span class="section-number-3">1.12 </span>execv()</h3>
<div class="outline-text-3" id="text-1-12">
<p>
<methode>int execv(char *ref, char *argv[])</methode>
</p><p>
permet le lancement de lexécution du fichier exécutable dont le nom est "ref",
avec comme arguments les chaînes pointées par argv[0],
</p><p>argv[1],...,argv[n]. argv[n+1] doit être contenir "NULL".
</p><p>Le code suivant reprend le code précédent en remplaçant l'appel à
execl par execv, et en utilisant un tableau de pointeurs sur les
arguments du exec.
</p><p>Contrairement au code précédent, on uilise ici la même référence pour
les paramètres "ref" et argv[0](ce qui est souvent le cas).
</p><pre> 1 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Exemple d'illustration des primitives Unix : Un père et ses fils */</font>
2 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* execv */</font>
3
4 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#include</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;</font>stdio.h<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&gt;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* entrées sorties */</font>
5 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#include</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;</font>unistd.h<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&gt;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* pimitives de base : fork, ...*/</font>
6 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#include</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;</font>stdlib.h<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&gt;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* exit */</font>
7 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#include</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;</font>sys/wait.h<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&gt;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* wait */</font>
8 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#include</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;</font>string.h<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&gt;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* opérations sur les chaines */</font>
9
10 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#define</font> NB_FILS 3 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* nombre de fils */</font>
11
12 <font style="--darkreader-inline-color:#ff72ff;" data-darkreader-inline-color="" color="purple">int</font> main<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font>
13 {
14 <font style="--darkreader-inline-color:#ff72ff;" data-darkreader-inline-color="" color="purple">int</font> fils, retour, wstatus, fils_termine <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
15
16 <font style="--darkreader-inline-color:#ff72ff;" data-darkreader-inline-color="" color="purple">char</font> *argv[8] <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* tableau de pointeurs sur les arguments du exec */</font>
17 <font style="--darkreader-inline-color:#ff72ff;" data-darkreader-inline-color="" color="purple">char</font> args_exec[8][16] <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* tableau des arguments du exec */</font>
18 strcpy<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>args_exec[0], <font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"./dormir"</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* arg0 */</font>
19 argv[0] <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> args_exec[0] <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* ponteur sur arg0 */</font>
20 strcpy<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>args_exec[1], <font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"3"</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* arg1 : durée de sommeil */</font>
21 argv[1] <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> args_exec[1] <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* ponteur sur arg1 */</font>
22 argv[2] <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> NULL <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* dernier pointeur <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> NULL */</font>
23
24 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"Je suis le processus principal de pid %d\n"</font>, getpid<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
25 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Vidange du tampon de sortie pour que le fils le récupère vide */</font>
26 fflush<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>stdout<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
27
28 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">for</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>fils <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> 1 <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> fils <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;=</font> NB_FILS <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> fils++<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> {
29 retour <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> fork<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
30
31 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Bonne pratique : tester systématiquement le retour des appels système */</font>
32 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">if</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>retour <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;</font> 0<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> { <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* échec du fork */</font>
33 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"Erreur fork\n"</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
34 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Convention : s'arrêter avec une valeur <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&gt;</font> 0 en cas d'erreur */</font>
35 exit<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>1<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
36 }
37
38 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* fils */</font>
39 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">if</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>retour <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">==</font> 0<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> {
40
41 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* mettre un executable inexistant pour le fils 2 */</font>
42 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">if</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>fils <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">==</font> 2<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> {
43 args_exec[0][3] <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> 'a' <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
44 }
45
46 execv<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>argv[0], argv<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* argv[0] utilisé comme nom de l'exécutable */</font>
47
48 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* on ne se retrouve ici que si exec échoue */</font>
49 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"\n Processus fils numero %d : ERREUR EXEC\n"</font>, fils<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
50 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* perror : affiche un message relatif à l'erreur du dernier appel systàme */</font>
51 perror<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">" exec "</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
52 exit<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>fils<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* sortie avec le numéro di fils qui a échoué */ </font>
53 }
54 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* pere */</font>
55 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">else</font> {
56 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"\nProcessus de pid %d a cree un fils numero %d, de pid %d \n"</font>,
57 getpid<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font>, fils, retour<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
58 fflush<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>stdout<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
59 }
60 }
61 sleep<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>3<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* pour les besoins de l'outil de validation automatique */</font>
62
63 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* attendre la fin des fils */</font>
64 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">for</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>fils <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> 1 <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> fils <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;=</font> NB_FILS <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> fils++<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> {
65 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* attendre la fin d'un fils */</font>
66 fils_termine <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> wait<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>&amp;wstatus<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
67
68 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">if</font> WIFEXITED<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>wstatus<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> { <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* fils terminé avec exit */</font>
69 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"\nMon fils de pid %d a termine avec exit %d\n"</font>,
70 fils_termine, WEXITSTATUS<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>wstatus<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
71 }
72 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">else</font> <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">if</font> WIFSIGNALED<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>wstatus<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> { <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* fils tué par un signal */</font>
73 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"\nMon fils de pid %d a ete tue par le signal %d\n"</font>,
74 fils_termine, WTERMSIG<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>wstatus<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
75 }
76 }
77 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"\nProcessus Principal termine\n"</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
78 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">return</font> <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">EXIT_SUCCESS</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
79 }
</pre>
<p>
Dans les deux versions précédentes, le fichier exécutable est trouvé grâce à son chemin
complet (./dormir).
</p><p>
<methode>execlp</methode> et <methode>execvp</methode> sont deux variantes de respectivement execl et execv, mais avec
recherche du fichier exécutable dans la liste des répertoires contenue dans la variable PATH.
</p></div>
</div>
<div id="outline-container-1-13" class="outline-3">
<h3 id="titre1-13"><span class="section-number-3">1.13 </span>Conservation des descripteurs</h3>
<div class="outline-text-3" id="text-1-13">
Les descripteurs ouverts avant l'appel à une primitive <methode>exec</methode>
le restent, et sont donc accessibles par l'exécutable lancé avec <methode>exec</methode>.
<p>
On peut illustrer cela en exécutant l'avant dernier programme en redirigeant
la sortie standard dans un fichier.
</p><p>
Mais l'appel à execl écrase le tampon de sortie ; ce qui induit un
risque de perte dinformation. Par exemple, si on introduit, dans le
fils, l'affichage d'un message avant l'appel à execl, ce message risque
de ne pas s'afficher s'il ne se
termine pas avec '\n' ou si l'exécution se fait avec redirection.
</p><p>
Pour forcer le vidage de ce tampon avant lappel à execl on utilise la fonction fflush() de la bibliothèque standard stdio.h.
</p><p>
Ce qui donne le code suivant :
</p><p>
</p><pre> 1 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Exemple d'illustration des primitives Unix : Un père et ses fils */</font>
2 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* execl et fflush */</font>
3
4 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#include</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;</font>stdio.h<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&gt;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* entrées sorties */</font>
5 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#include</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;</font>unistd.h<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&gt;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* pimitives de base : fork, ...*/</font>
6 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#include</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;</font>stdlib.h<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&gt;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* exit */</font>
7 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#include</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;</font>sys/wait.h<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&gt;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* wait */</font>
8
9 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">#define</font> NB_FILS 3 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* nombre de fils */</font>
10
11 <font style="--darkreader-inline-color:#ff72ff;" data-darkreader-inline-color="" color="purple">int</font> main<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font>
12 {
13 <font style="--darkreader-inline-color:#ff72ff;" data-darkreader-inline-color="" color="purple">int</font> fils, retour, wstatus, fils_termine <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
14
15 <font style="--darkreader-inline-color:#ff72ff;" data-darkreader-inline-color="" color="purple">char</font> ref_exec[]<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"./dormir"</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* exécutable */</font>
16 <font style="--darkreader-inline-color:#ff72ff;" data-darkreader-inline-color="" color="purple">char</font> arg0_exec[]<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"je dors"</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* argument0 du exec : nom donnée au processus */</font>
17 <font style="--darkreader-inline-color:#ff72ff;" data-darkreader-inline-color="" color="purple">char</font> arg1_exec[]<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"3"</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* argument0 du exec : durée de sommeil */</font>
18
19 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"Je suis le processus principal de pid %d\n"</font>, getpid<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
20 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Vidange du tampon de sortie pour que le fils le récupère vide */</font>
21 fflush<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>stdout<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
22
23 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">for</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>fils <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> 1 <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> fils <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;=</font> NB_FILS <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> fils++<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> {
24 retour <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> fork<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
25
26 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Bonne pratique : tester systématiquement le retour des appels système */</font>
27 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">if</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>retour <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;</font> 0<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> { <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* échec du fork */</font>
28 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"Erreur fork\n"</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
29 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Convention : s'arrêter avec une valeur <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&gt;</font> 0 en cas d'erreur */</font>
30 exit<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>1<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
31 }
32
33 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* fils */</font>
34 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">if</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>retour <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">==</font> 0<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> {
35 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"\n Processus fils numero %d, de pid %d, de pere %d.\n"</font>,
36 fils, getpid<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font>, getppid<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
37
38 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Précaution en cas d'une exécution avec redirection : */</font>
39 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* Vidange du tampon de sortie avant qu'il ne soit écrasé par exec */</font>
40 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* D'après le standard ISO le comportement du printf présente 2 cas : */</font>
41 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* - sortie interactive <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>terminal<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> : flot géré par ligne et \n provoque */</font>
42 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* la vidange du tampon langage */</font>
43 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* - sortie dans un fichier : flot géré par bloc et \n est traité comme */</font>
44 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* un caractère ordinaire. fflush<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>stdout<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> force la vidange du tampon. */</font>
45 fflush<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>stdout<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
46
47 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* executable inexistant pour le fils 2 */</font>
48 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">if</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>fils <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">==</font> 2<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> {
49 ref_exec[3] <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> 'a' <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
50 }
51
52 execl<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>ref_exec, arg0_exec, arg1_exec, NULL<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
53
54 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* on ne se retrouve ici que si exec échoue */</font>
55 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"\n Processus fils numero %d : ERREUR EXEC\n"</font>, fils<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
56 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* perror : affiche un message relatif à l'erreur du dernier appel systàme */</font>
57 perror<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">" exec "</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
58 exit<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>fils<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* sortie avec le numéro di fils qui a échoué */ </font>
59 }
60 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* pere */</font>
61 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">else</font> {
62 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"\nProcessus de pid %d a cree un fils numero %d, de pid %d \n"</font>,
63 getpid<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font>, fils, retour<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
64 fflush<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>stdout<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
65 }
66 }
67 sleep<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>3<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* pour les besoins de l'outil de validation automatique */</font>
68
69 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* attendre la fin des fils */</font>
70 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">for</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>fils <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> 1 <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> fils <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">&lt;=</font> NB_FILS <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font> fils++<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> {
71 <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* attendre la fin d'un fils */</font>
72 fils_termine <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">=</font> wait<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>&amp;wstatus<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
73
74 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">if</font> WIFEXITED<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>wstatus<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> { <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* fils terminé avec exit */</font>
75 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"\nMon fils de pid %d a termine avec exit %d\n"</font>,
76 fils_termine, WEXITSTATUS<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>wstatus<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
77 }
78 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">else</font> <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">if</font> WIFSIGNALED<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>wstatus<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> { <font style="--darkreader-inline-color:#72ff72;" data-darkreader-inline-color="" color="green">/* fils tué par un signal */</font>
79 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"\nMon fils de pid %d a ete tue par le signal %d\n"</font>,
80 fils_termine, WTERMSIG<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font>wstatus<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
81 }
82 }
83 printf<font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">(</font><font style="--darkreader-inline-color:#ffae1a;" data-darkreader-inline-color="" color="orange">"\nProcessus Principal termine\n"</font><font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">)</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
84 <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">return</font> <font style="--darkreader-inline-color:#337dff;" data-darkreader-inline-color="" color="blue">EXIT_SUCCESS</font> <font style="--darkreader-inline-color:#ff1a1a;" data-darkreader-inline-color="" color="red">;</font>
85 }
</pre>
</div>
</div>
</div>
</div>
</div>
</body></html>