From 831c8199f66fee18c68fcc56c96767cca5591e61 Mon Sep 17 00:00:00 2001 From: Matthew Fitzsimmons Date: Sat, 21 Jan 2012 21:02:16 -0700 Subject: [PATCH 01/36] Nodejs.org design refresh. --- doc/about/index.html | 65 +++++++--- doc/api_assets/style.css | 242 ++++++++++++++++++++++++++++++++---- doc/community/index.html | 256 ++++++++++++++++++++++----------------- doc/ebay-logo.png | Bin 2354 -> 1206 bytes doc/index.html | 18 ++- doc/logos/index.html | 36 +++++- doc/pipe.css | 246 +++++++++++++++++++++++++++++++++---- doc/sh_vim-dark.css | 10 ++ doc/template.html | 61 ++++++++-- 9 files changed, 735 insertions(+), 199 deletions(-) diff --git a/doc/about/index.html b/doc/about/index.html index f3a33554f48..549b8d6f033 100644 --- a/doc/about/index.html +++ b/doc/about/index.html @@ -18,15 +18,41 @@ href="http://feeds.feedburner.com/nodejs/123123123"> node.js - -
+ +
+ +
-

About

+

Node's goal is to provide an easy way to build scalable + network programs

+ + +

In the "hello world" web server example + below, many client connections can be handled concurrently. + Node tells the operating system (through epoll, + kqueue, /dev/poll, or + select) that it should be notified when a new + connection is made, and then it goes to sleep. If someone new + connects, then it executes the callback. Each connection is + only a small heap allocation.

 var http = require('http');
@@ -35,17 +61,6 @@ http.createServer(function (req, res) {
   res.end('Hello World\n');
 }).listen(1337, "127.0.0.1");
 console.log('Server running at http://127.0.0.1:1337/');
- -

Node's goal is to provide an easy way to build scalable - network programs. In the "hello world" web server example - above, many client connections can be handled concurrently. - Node tells the operating system (through epoll, - kqueue, /dev/poll, or - select) that it should be notified when a new - connection is made, and then it goes to sleep. If someone new - connects, then it executes the callback. Each connection is - only a small heap allocation.

-

This is in contrast to today's more common concurrency model where OS threads are employed. Thread-based networking is relatively inefficient and very difficult to use. See:

  • Slides from JSConf 2010
  • Video from a talk at Yahoo in May 2010
  • -

    Go back to the home page

    -
    -
    + diff --git a/doc/api_assets/style.css b/doc/api_assets/style.css index c47f3812b84..b5665d53b72 100644 --- a/doc/api_assets/style.css +++ b/doc/api_assets/style.css @@ -1,18 +1,22 @@ /*--------------------- Layout and Typography ----------------------------*/ +html { + -webkit-font-smoothing: antialiased; +} + body { -// font-family: "Helvetica Neue", Helvetica, FreeSans, Arial, sans-serif; - font-family: Georgia, FreeSerif, Times, serif; - font-size: 0.9375em; - line-height: 1.4667em; - color: #222; - margin: 0; padding: 0; + font-family: "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Verdana, Tahoma, sans-serif; + font-size: 14px; + line-height: 180%; + color: black; + margin: 0; padding: 40px 0 0 0; + border-top: 6px #8CC84B solid; } a { - color: #0050c0; + color: #669900; text-decoration: underline; } a:visited { - color: #b950b7; + color: #46483e; text-decoration: underline; } a:hover, a:focus { @@ -28,6 +32,18 @@ a { display: none; } +#gtoc a { + font-family: Georgia, FreeSerif, Times, serif; + font-size: 16px; + text-decoration: none; + color: #46483e; +} + +#gtoc a:hover { + color: #669900; + text-decoration: underline; +} + .notice { display: block; padding: 1em; @@ -89,15 +105,18 @@ dd + dt.pre { } h1, h2, h3, h4, h5, h6 { - font-family: Georgia, FreeSerif, Times, serif; + font-family: Helvetica, Arial, sans-serif color: #000; text-rendering: optimizeLegibility; position: relative; } h1 { - font-size: 2.55em; - line-height: 1.375em; + font-family: Georgia, FreeSerif, Times, serif; + font-size: 30px; + font-weight: normal; + line-height: 36px; + color: #669900; } h2 { @@ -159,12 +178,13 @@ h6 { } pre { - padding: 2em 1.6em 2em 1.2em; + padding: 1em 1.6em 1em 1.2em; vertical-align: top; background: #f8f8f8; border: 1px solid #e8e8e8; border-width: 1px 1px 1px 6px; margin: -0.5em 0 1.1em; + overflow-x:auto; } pre + h3 { @@ -175,28 +195,27 @@ code.pre { white-space: pre; } -#container { - position: relative; - padding: 6em; - max-width: 50em; - text-align: left; +#intro { + width: 775px; + margin: 0 auto; + text-align: center; + color: #d2d8ba; + + /* preload platform-icons.png */ + background-image: url(platform-icons.png); + background-repeat: no-repeat; + background-position: -1000px -1000px; } -#container header { - margin: 1.25em -0.5em 1.3em; - padding: 0 0.5em 0.225em; +#intro.interior #logo { + margin-left: -130px; } hr { background: none; border: medium none; border-bottom: 1px solid #ccc; - margin: 5em 0 2em; -} - -#container header hr { - margin: 0; - padding: 0; + margin: 2em 0 2em; } #toc { @@ -242,3 +261,174 @@ a.octothorpe { h6:hover > a.octothorpe { opacity: 1; } +#content { + width: 800px; + margin: 0 auto; + overflow: visible; + clear: both; + display: block; +} + +#column1.interior { + width: 590px; + float: right; + padding-top: 20px; +} + +#column2.interior { + width: 160px; + float: left; + margin-top: -50px; + overflow: visible; +} + +#column2.interior ul { + margin-left: 0; +} + +#column2.interior li { + list-style-type: none; +} + +#column2.interior li a { + display: block; + padding: 0 0 0 40px; + color: #878b78; + text-transform: uppercase; + text-decoration: none; + font-size: 12px; + line-height: 23px; +} + +#column2.interior li a.home { background: url(icons-interior.png) no-repeat -158px 3px; } +#column2.interior li a.download { background: url(icons-interior.png) no-repeat -158px -21px; } +#column2.interior li a.about { background: url(icons-interior.png) no-repeat -158px -44px; } +#column2.interior li a.npm { background: url(icons-interior.png) no-repeat -158px -70px; } +#column2.interior li a.docs { background: url(icons-interior.png) no-repeat -158px -93px; } +#column2.interior li a.blog { background: url(icons-interior.png) no-repeat -158px -117px; } +#column2.interior li a.community { background: url(icons-interior.png) no-repeat -158px -140px; } +#column2.interior li a.logos { background: url(icons-interior.png) no-repeat -158px -164px; } +#column2.interior li a.jobs { background: url(icons-interior.png) no-repeat -158px -189px; } + +#column2.interior li a.home.current { background-position: left 3px; } +#column2.interior li a.download.current { background-position: left -21px; } +#column2.interior li a.about.current { background-position: left -44px; } +#column2.interior li a.npm.current { background-position: left -70px; } +#column2.interior li a.docs.current { background-position: left -93px; } +#column2.interior li a.blog.current { background-position: left -117px; } +#column2.interior li a.community.current { background-position: left -140px; } +#column2.interior li a.logos.current { background-position: left -164px; } +#column2.interior li a.jobs.current { background-position: left -189px; } +#column2.interior li a.current { color: #8cc84b; font-weight: bold; } + +#column2.interior li a.home:hover { background-position: -333px 3px; } +#column2.interior li a.download:hover { background-position: -333px -21px; } +#column2.interior li a.about:hover { background-position: -333px -44px; } +#column2.interior li a.npm:hover { background-position: -333px -70px; } +#column2.interior li a.docs:hover { background-position: -333px -93px; } +#column2.interior li a.blog:hover { background-position: -333px -117px; } +#column2.interior li a.community:hover { background-position: -333px -140px; } +#column2.interior li a.logos:hover { background-position: -333px -164px; } +#column2.interior li a.jobs:hover { background-position: -333px -189px; } +#column2.interior li a:hover { color: #000000; text-decoration: none; } + +#column2.interior li + li { + border-top: 1px solid #c1c7ac; +} +#column2.interior p.twitter { + padding-top: 20px; +} + +#column2.interior p.twitter a { + background: url(twitter-bird.png) no-repeat 0 4px; + padding-left: 37px; + text-decoration: none; +} + +#column2.interior p.twitter a:hover { + text-decoration: underline; +} + +a.totop { + font-family: "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Verdana, Tahoma, sans-serif; + font-weight: bold; + text-indent: -9999999px; + background: url(anchor.png) no-repeat top left; + margin-right: 7px; + display: block; + width: 13px; + border-bottom: 1px solid #cccccc; +} + +a.anchor { + font-family: "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Verdana, Tahoma, sans-serif; + font-weight: bold; + text-indent: -9999999px; + background: url(anchor.png) no-repeat top right; + display: block; + width: 13px; + border-bottom: 1px solid #cccccc; +} +#footer { + width: 775px; + border-top: 1px solid #626557; + margin: 50px auto 30px auto; + padding-top: 15px; +} + +#footer p { + color: #8BC84B; + font-size: 10px; + padding-left: 195px; + color: #878b78; +} + +#footer p a { + text-decoration: underline; + color: #878b78; +} + +#footer ul { + background: url(footer-logo-alt.png) left top no-repeat; + padding-left: 195px; + height: 26px; + padding-top: 6px; + margin-left: 0; +} + +#footer ul li { + list-style-type: none; + display: block; + float: left; + font-size: 12px; +} + +#footer ul li a { + margin: 0; + padding: 0; +} + +#footer ul li + li { + height: 12px; + margin-left: 3px; +} + +#footer ul li + li a { + padding: 0 0 0 4px; + border-left: 1px solid #878b78; +} + +#footer ul li a.twitter { + background: url(twitter-bird.png) no-repeat 0 2px; + padding-left: 19px; +} + +/* simpler clearfix */ +.clearfix:after { + content: "."; + display: block; + height: 0; + clear: both; + visibility: hidden; +} + diff --git a/doc/community/index.html b/doc/community/index.html index 3219f7bf847..13387987f41 100644 --- a/doc/community/index.html +++ b/doc/community/index.html @@ -21,134 +21,166 @@ node.js -
    +
    + +
    -

    Node's most valuable feature is the friendly and colorful - community of developers. There are many places where - this group congregates on the internet. This page attempts - to highlight the best forums.

    +

    Node's most valuable feature is the friendly and colorful community of developers. There are many places where this group congregates on the internet. This page attempts to highlight the best forums.

    -

    Periodicals

    +
    +
    +

    Documentation

    -

    Planet Node is an - aggregator of Node developer blogs. NodeUp - is a podcast covering the latest Node news in the - community.

    +

    official API docs

    +

    docs.nodejitsu.com answers many of the common problems people come across.

    +

    How To Node has a growing number of useful tutorials.

    +

    Stack Overflow node.js tag collects new information every day.

    +
    -

    Docs

    -

    - Besides the official API - docs there are a number of sites new users should be - aware of. docs.nodejitsu.com - answers many of the common problems people come across. - How To Node has a - growing number of useful tutorials. - The Stack - Overflow node.js tag is collecting new information - every day. +

    +

    GitHub

    +

    All development takes place at http://github.com/joyent/node. + The comments on commit messages are often source of heated + discussion regarding core development.

    The GitHub Node + wiki is full of useful links for newcomers. Don't + miss Projects, + Applications, and Companies Using Node or the very + long list of Node modules, many of which are + published in the npm + registry.

    +
    +
    + - -

    GitHub

    -

    All development takes place at http://github.com/joyent/node. - The comments on commit messages are often source of heated - discussion regarding core development. The GitHub Node - wiki is full of useful links for newcomers. Don't - miss Projects, - Applications, and Companies Using Node or the very - long list of Node modules, many of which are - published in the npm - registry.

    +
    +
    +

    Mailing Lists

    +

    The user + mailing list is used for announcements, discussion, + and flame wars about Node. The internal + development mailing list is used for discussion of + internal design and feature proposals.

    +
    + +
    +

    Periodicals

    + +

    Planet Node is an + aggregator of Node developer blogs.

    NodeUp + is a podcast covering the latest Node news in the + community.

    +
    +
    + +
    +
    +

    Conferences

    + +

    NodeConf + conferences are the main event in the United States; they + are organized by Mikeal Rogers.

    +

    NodeFest (東京Node学園祭) + is organized by the Node.js + Japan user group.

    +

    NodeCamp.de in Cologne, + Germany is organized by Rails Love.

    +

    An Italian + Node.js Conference exists as well.

    +

    Node Summit is a + conference in San Francisco focusing on the adoption of + Node in larger companies.

    +

    JSConf organizes the main + JavaScript conferences.

    +
    + +
    +

    Localized Sites

    + +

    nodejs.org does not maintain any + translations into other languages. However there are + community websites in various languages with mailing lists + and translations of the website.

    + +

    nodejs.ru Russian blog. +
    + nodejs.ir Iran group in Persian +
    + nodejs.jp Japan user group +
    + CNodeJS.org Chinese community +
    + nodejs.co.il Israeli wiki +
    + HKNoJ Hong Kong community +
    + nodejs.tw Taiwan community

    +
    +
    + +
    +
    +

    IRC

    + +

    For real-time chat about Node development go to + irc.freenode.net in the #node.js + channel with an IRC client or connect in + your web browser to the channel using freenode's + WebChat. Felix Geisendörfer keeps logs of the + channel for those who miss a day.

    +
    +
    +

    Bugs - should be reported to https://github.com/joyent/node/issues. - Fixes to the code are welcome! Please see our contributing - guidelines for information on how to submit a - patch.

    - -

    Mailing Lists

    - -

    The user - mailing list is used for announcements, discussion, - and flame wars about Node. The internal - development mailing list is used for discussion of - internal design and feature proposals.

    - -

    IRC

    - -

    For real-time chat about Node development go to - irc.freenode.net in the #node.js - channel with an IRC client or connect in - your web browser to the channel using freenode's - WebChat. Felix Geisendörfer keeps logs of the - channel for those who miss a day.

    - -

    Conferences

    - -

    NodeConf - conferences are the main event in the United States; they - are organized by Mikeal Rogers. - NodeFest (東京Node学園祭) - is organized by the Node.js - Japan user group. NodeCamp.de in Cologne, - Germany is organized by Rails - Love. An Italian - Node.js Conference exists as well. Node Summit is a - conference in San Francisco focusing on the adoption of - Node in larger companies. JSConf organizes the main - JavaScript conferences.

    - -

    Localized Sites

    - -

    nodejs.org does not maintain any - translations into other languages. However there are - community websites in various languages with mailing lists - and translations of the website.

    - -

    nodejs.ru Russian blog. -
    - nodejs.ir Iran group in Persian -
    - nodejs.jp Japan user group -
    - CNodeJS.org Chinese community -
    - nodejs.co.il Israeli wiki -
    - HKNoJ Hong Kong community -
    - nodejs.tw Taiwan community

    -

    Go back to the home page

    + src="not-invented-here.png" width="100%">

    -
    -
    diff --git a/doc/logos/index.html b/doc/logos/index.html index 35c575cb551..dab67fce599 100644 --- a/doc/logos/index.html +++ b/doc/logos/index.html @@ -22,14 +22,29 @@ node.js -
    +
    + +
    -

    To echo the evolutionary nature of Node, we've added some punch and playfulness to its identity. All it needs now is a good home with you, download and have fun!

    Logo Downloads

    @@ -54,17 +69,28 @@

    Select your screen resolution:
    1024 x 768
    | 1280 x 1024 | 1440 x 900 | 1920 x 1200 | 2560 x 1440

    -

    Go back to the home page

    -
    -
    + From 4fd315192a2b705cb9b0501f45cd47d9ee109ac7 Mon Sep 17 00:00:00 2001 From: isaacs Date: Sun, 22 Jan 2012 14:06:17 -0800 Subject: [PATCH 02/36] Add images to doc_assets --- doc/anchor.png | Bin 0 -> 509 bytes doc/api_assets/anchor.png | Bin 0 -> 509 bytes doc/api_assets/footer-logo-alt.png | Bin 0 -> 2037 bytes doc/api_assets/icons-interior.png | Bin 0 -> 5177 bytes doc/api_assets/logo-light.png | Bin 0 -> 1448 bytes doc/api_assets/platform-icons.png | Bin 0 -> 3593 bytes doc/api_assets/twitter-bird.png | Bin 0 -> 351 bytes doc/community-icons.png | Bin 0 -> 6901 bytes doc/footer-logo-alt.png | Bin 0 -> 2037 bytes doc/home-icons.png | Bin 0 -> 2107 bytes doc/icons-interior.png | Bin 0 -> 5177 bytes doc/logo-light.png | Bin 0 -> 1448 bytes doc/twitter-bird.png | Bin 0 -> 351 bytes 13 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 doc/anchor.png create mode 100644 doc/api_assets/anchor.png create mode 100644 doc/api_assets/footer-logo-alt.png create mode 100644 doc/api_assets/icons-interior.png create mode 100644 doc/api_assets/logo-light.png create mode 100644 doc/api_assets/platform-icons.png create mode 100644 doc/api_assets/twitter-bird.png create mode 100644 doc/community-icons.png create mode 100644 doc/footer-logo-alt.png create mode 100644 doc/home-icons.png create mode 100644 doc/icons-interior.png create mode 100644 doc/logo-light.png create mode 100644 doc/twitter-bird.png diff --git a/doc/anchor.png b/doc/anchor.png new file mode 100644 index 0000000000000000000000000000000000000000..1ed163ee1a159ea92efcca92a557e93cd434419c GIT binary patch literal 509 zcmV!R z_V)Dj@$Ks7>FMb3^78TT>f74c%*@L1@$uf?-PP36&eGD)&(8n<|H;Y6%gf2h$;QXY z$KT)H%F4*&+9;~>g&bH$K&PW z%*@8_@$%u`*xTIO=;!9&+}7jc;K|9v>+0p!)z0kcFWOe{pRWD=;-I}?(N{^cd+)vf z|6iE|&T$=lt4S93B$ElFzcSs>b5kH;7yj?_I6gfaom030r+yHyPnb?Q%f}=Ay%6IDHFvnh0%@I}?Zp@A3`FkZOzd5Uz$`wWD1%3~~K zDH$Djt1Im=;Db~CF(dC-$?_8}6pF_1d<7T)X{APSoQl`=00000NkvXXu0mjfVFxF^ literal 0 HcmV?d00001 diff --git a/doc/api_assets/anchor.png b/doc/api_assets/anchor.png new file mode 100644 index 0000000000000000000000000000000000000000..1ed163ee1a159ea92efcca92a557e93cd434419c GIT binary patch literal 509 zcmV!R z_V)Dj@$Ks7>FMb3^78TT>f74c%*@L1@$uf?-PP36&eGD)&(8n<|H;Y6%gf2h$;QXY z$KT)H%F4*&+9;~>g&bH$K&PW z%*@8_@$%u`*xTIO=;!9&+}7jc;K|9v>+0p!)z0kcFWOe{pRWD=;-I}?(N{^cd+)vf z|6iE|&T$=lt4S93B$ElFzcSs>b5kH;7yj?_I6gfaom030r+yHyPnb?Q%f}=Ay%6IDHFvnh0%@I}?Zp@A3`FkZOzd5Uz$`wWD1%3~~K zDH$Djt1Im=;Db~CF(dC-$?_8}6pF_1d<7T)X{APSoQl`=00000NkvXXu0mjfVFxF^ literal 0 HcmV?d00001 diff --git a/doc/api_assets/footer-logo-alt.png b/doc/api_assets/footer-logo-alt.png new file mode 100644 index 0000000000000000000000000000000000000000..e6d9c2390e376f8a85e372f99da1048043bb6a45 GIT binary patch literal 2037 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 HL&yFb=7W;V literal 0 HcmV?d00001 diff --git a/doc/api_assets/logo-light.png b/doc/api_assets/logo-light.png new file mode 100644 index 0000000000000000000000000000000000000000..898fcecc96fb49845d8287a89ee647b94b6af0b7 GIT binary patch literal 1448 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 bUjY$i*Fo;mzbqfE|C|}<8tEi!S>65*@!6*! literal 0 HcmV?d00001 diff --git a/doc/api_assets/twitter-bird.png b/doc/api_assets/twitter-bird.png new file mode 100644 index 0000000000000000000000000000000000000000..b619b2a0d3d6b378dd72feb987d0e97f61d59c4a GIT binary patch literal 351 zcmV-l0igbgP)cwW1%*7 z5&}w^Ku8zU2LqOYR1!>SCq99d4`5{_3U-#JNic;5d;*Io!O9|ng#-nYe_@1W*+mCF zZrRzLyPF9%#`l2};{i{oVy-7VZ5=}aVM~D=`Y57?gsaF#4lVG4sO$&PleI57btY~r z@`qO>(ZmXOxI)(WvIyz{t+F1U;zka>Ve9Bo2@?!FBQe95<*l|*`_DM@EyWB1780!v(@qK(*$7RvgDFQa|OFWSgB xE)S(&BQxO}jXFmPmq<%tHL)pvT>thjzyK!*F6VT)7##or002ovPDHLkV1i^;gYEzT literal 0 HcmV?d00001 diff --git a/doc/community-icons.png b/doc/community-icons.png new file mode 100644 index 0000000000000000000000000000000000000000..b3d58f0f1eb476676c768c052f9eb814186e08e9 GIT binary patch literal 6901 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 OfETJSRqB*p$NU!%d=2aX literal 0 HcmV?d00001 diff --git a/doc/footer-logo-alt.png b/doc/footer-logo-alt.png new file mode 100644 index 0000000000000000000000000000000000000000..e6d9c2390e376f8a85e372f99da1048043bb6a45 GIT binary patch literal 2037 zcmbVNX;c&E8jd1GkZ`Qm1!QS%084u%nF$G51Z-du;9zKgSdfYmk_iNoOh^V3xL9zB z*5y`^VpwFY-YZcMETEt)rBI51fS|3o(H2xHpj<%&igco2`@_>8opWZs@BQX^-u<09 z#1HhvTdcRh;c$3=KPVVmW3bz9xe4~HjkkcX#Rlbsp&^I_)d*EEjx9!_V1mC~7!3!* zLUCez8|;C@nMkC9Ff@#}g(X7dB%u*Q(#n+>8;A4QtW^p{aWG1Vf}^DhPvVoy4Mc)e z>`4rz@c^FE2ab{YC8^+$q(FfvDNe)`6E}MiJhUuKfgDDK1g%`AP_wk2#8-M**xqk7!4P-B7AAQTV^CDdB9k>54N2ohLR8UYkjZ3{0ScKyam5g>>O=)9)VeCv zj*A)~SS?aXm8cX^5R4jyQAh&nNyI#T9fDlR4S0LZF?P}}6&-duFj^`KT?EXxnNsOPLpFf$WfBEv|+}vDBYSN1r zQ^(Q{KY22yP{y==-;#S$fAfbMj~+d2XuNX1{M^LEv!h=eOxT57>*~NE8xLb&k8S=C zTcGW)Jh6Lc@kc9Lx2;~C(71*Y)Yt6P`H9DS9|jE1HJrVjt;0Q@LGRYg1MObP*|+X@ z6r0Dkj@=nptC{KgnJ9OqCO1#6yihG3vZs#iN*t}u+dc){{oZ^WWMlL3onSGnGv@`@SqYf9uy57=! zX`^_#&M)O6?Y>Lu@xJ=$`uPWt-Yys=)x?Vv&+QU?9h zdvD+?-@?|1g?l(A&vGhf%LV)J2`4qbe!5N-WZMy!(^g;(jTb$Y-isz&PI{-->^45j zHt30E-v!}SEBd=*fX$B+(kKT10uCh0c8ErOvXRrH{kjX#=mp#lEEPMoe6$ zT-rk~Wz?Os)`go_9-$l?^U^x8XX-1oCEdAX4_0`=_p>Ew<&;Mhj}puGwfR$=#P-Rr zeoJk5>X&~$Rxs?Dio0S@Mpyoi5LLv6o+>nM(^B56c@C6lqrI$%j> zL>JDMeQ3&t88&gvFmzPtA_=&SgKg0?4V%xho?Vw{(SHI&HFs> zeWoftR_y8S?@l6-JQ0a7kvRWMA}wONITO-lSMwNg_~CF0t}tnFJ8Hp5JdG(EBO?Yh z2TR0IO~Hn*u(c$TvsR}}!BgZh9JR?nL+5O04uhFMlSpf$9A;Fl$8d5smZLLrDUUlY zP{=wBmy*nsgL1O~%hgE=EtsM(R;e!3t0Od&s7Uf!2ZtaqU^q&481jr(j)O~i$;%<+ zxodzzerba1xs+EyrO4yS0+R(JGihL`8VrZX;S3tY03#R?A!IrTfdE7YKvpOOa+oX* z2$AO>3gOM7(Q*=nqIqA0#--%qxS0b0cDtQs52KkZIRF$95dna7fKCr3EJCdXMjUm7 z8m-g?1|eouTXbezXEKuK7}0E#4d+sbNMEI3Fw5nyiH+9zLJ=hc9H<$9XdqxP%;ojc z+KMM)zlHHeYpb%ri~)(5)nv1%iGFCQ3t*ylzwcqOvw5E+yJf3#Xg;*k)mVqZr>Sb~K5r zdt^D~LSr4g-pIE#h?6j$d|i}r2dpU(sy7KL&P$7rO7gbB5_x2dBC5JqR?{on(jkpa ziYjkMBr%ax>S@($00zvs%>DF!;B9E%>mf81VU;aN@DJJqJLo{w&2$3+1VRG8PmgG zhWNP&w7!#@+Njg*|9LtP{An$+&OpM_c-iZGc7D89*5X~gTPbzdHjkWCsgBg%y15ul zi`hV}%9qCVJKZ_-b^=`PCEQ*0kIm15w?13sPnp=>wR?Z6f6)>))x$gfz_{baH5C$c zddN%K_JPOL>43he!pg?YHYg;iYcO#9uwk0vL%rmZ!8@`A9pa8Kd`vlIjoY&MiBf&S zKqY!lA8#wW{B5cJss-0SbiK13PDmIikp0M8oV40kv#YjrEbQ~h#XL>Y?aH^GrZ5-g4wzB@90ddV!reo~6ngyZ+WsrD@MqV@*HzH|QP) zu78Z!Mgig7<(JC!NRw(b^ZaMqK5_S$(5A=rA1GK_Q5YEV?R)LlNoxj}z6X+go&WR~ z&*=MB|CBv{*RDU5-gDycse{$Jn{f^Gh7|{$Slv-5n(kG=edl)P((h|M_S|rvh}}rq z2_OCDZ_}qFkuLk}cR4@R3>`E9Yu5bIIN8^e6zodBR?{3d7>2H5q^|s-KdHCBzBHk; zYtk>}Ojk%mfP&uZ)_uO>8u(##H5mRCNd5JsZY89?^_d?n^>deAghQnrZEv@?t*!L9 zr%L|f%T+*n!hpDvC(YB7MiQGE%9$sguWp^t3tSFVAG6-vi0mlyR({;#b$$QWOgCy> z`pMIE>mTRt${5*RxW(Ty-|cwYFl(@CkUZ6wr`qw*b9m_XN>-6im!hIAm^uA@YSrDo zk6M56SiZct|OaJeXRxuT@K$a$&uN7B;H03fLCdB-O7L0!k_vU9%a<74%%MQ?p@>DEj^S-ta2 z!MUl?$sUhK4Hr)Y7sqA&+xV;H{*qa)%d;u*lbJh#?C;*YHt>h3nV+E-=1GMmv-M(0 zP-gHATf#t2m9_q_n11kSQwqP2v6rX9{i$tg8&$2=S;))$=M|!sY6IDyIwX%SOs3D@~`Y zn@Q26DX1-KMy1wdN{CyLR<7i}aet^a@4a_E?;n>x?@dS{4I5~`qe&>eF;0V?PINd* z&)3Qo>Kcb7L`6F%#}jbL2fgsgF?d9{o*i1pmW~7z5DAn}9Xc_Vlz^n8^j7pDfothw zh@Q@h2qgxkx9XIitGf=C98b`(GJ~4pq1G@RYfCejB@|(aFwrrG!k`eCIRpwfg+Y;4 za3mC_v-Z>i^{%AUz$O)@%WHD7`2OB@PLJ&}cL>nuQrTJ`w^$AP^9!ImF!D6p%1Y zNFq@}>87Lv{cjo^2?_Z4=r~F=nWQ7t7#c=Sq@eTwPgg@A#<{wFS4>J+OB9eY2t70o z0yBd`h(u{zE7A!RPr~1B{G)V&S5h1S;z>v#C&uG}dPL}dI}GIRKO2$?0^T6q;-i70 zgvL6O@rgtNiL%cTr3bt*3y%&*LJ_;6Fc{nt3O9#Z?}ov4!(mQ)%y&aAp^jEg@ICh5 zbo|p^@QgC6t6Ge6t%3*j+oj z`#+vVV&e&+6mq;5nH>8K0q#*`3OON)9H)cDS?Rcj;-g8@due%Aqje<2M^g#mPVr=- z&Pslf(f?rIaSse?zT0ZIxxG0|8aDz4ML1YMEghj278VFcnBLmi@c&QFAb>LvDLDQO zEZ-gh2$Wuahdyxgy?F>Epkv~J*4VA|8x90gjo#;I??rz%Ec_vV2Vq63=gMCLOO8!sI+99u#Nj^a{3kRwQEY|da6ey zaq8rmv?Y;@bImOK9`Y?`X$F01%c;}qT3TtXPv__7FQ(l_&s2K5 zPUtWOHH=pG9VMk_!kYpKXC=HMuu!9UQkhSwZg_lbYnMcB$+u_6kk8dmn(R-cvd72d zm+<-xt)@%ch8%%s*ALK^=wAd$O&~G|st3GAq@qUsfN&wu2a@zF6i~#;5kc+LsJK0JgRA~nz_Nil*B7*6iZB|0Nz)Wf0e|xklzU8s9 z536W)x1G>w*DIR?`>|N;eU5;K=_&R;^#cY-(NCjCx;<&Q8IO?9Q0bN&O*mB|$*lM@VJO@IF^Yu7P#k6XqDHYyf^|d&G-=SBBZvq8{Coqt=I0 z!971-$O-$)=D^&jwNVix4&hkil;ph4?88P;A#Z_s-!CspKRG*=BN%?1 z?~3L64wgWM;zfhJ-lYVN!Gb}g5y!aLd-PDsp-U@JJ*>lGU8>ko5?FGnWU+G6YS19S zc&}mhd}H;qbcjIK>eX8I^p8F&H_YCpW;@Wv%Ra|4x_7P&{PYhG?KNg5r$auHgvs>bR!2)vU57W(>?g3 zV#BS;finy1NM2NDlSOp;OP^SMFUK(qZ8JE@GTmdjPw`3<6;lY5zC$>GN$cLqzRULi z^rh1MqoG?C{kH`E&gF{%eC1V@a^f=HhWc^w5fz)a+)Bw|`O@-2v?Q6Jn2vIntpf{P zmBJTtOM-&fUUMbv(EbFfEbqSV@{bdoD;ufDzV2mi;We#USHy8!(u`&kdpnjLatdeo zNr`q7?{%wAk~(7~e>J2fig3EYYEi6(4FUx#AX;I5J!PIE+Jb%rU*8reM|b)3QU$R=> zFzwajG0PRc9CFh|Us+llAAT;&s9mWto=F}*F4h+T(^{0tyO?&M@pN|gwt+{nC6`x$ zn@MKBIFs4^c;0C%Q1Q+nQh)*o^>6L2-U5;W51KC{C4fUZU=Z-+A%MnH*}~@or&Pz< z_#~=tnZ93B)G=wTYX#%7tShr0#3!`fj%t#XEU`dwTtYgF>7n<2%T_~IUm|8|3~3IL z`lOw%1gJj1W^j?W)^E<}(Y-bLPGxGi{54+lOh9mdn|?z`i}fP|sq{^bb^aNJPsRHo zkz`p-X~A9QpU(Oo>Ut6^Ut2Q+v^0UX-D-IYXlK|M_<~p{GEoE#ZTz1e12IVZ2Z-U} zPp_l;V|;MIWff%=MycJEPIJGC$v*l>zz5FgX{-E5gI>>Rk5S052g@tC#P-H8YcY?Q zVO>gVVRP`B>^r&jH^nj{ZyuF*n%BxZ!fWPb^4`YE|GBXadtOMi&Y!_m`jEVWZ>I*= z1lPRYx_m*LA&wRu5t$S(KcoZ2lMaM5{~R~(%ax1XH3w?Ew|Pbw+Idr_-v9K)IK(Ho z{L%-O%;yqXOFic%z9nYfA;Q>YfAPWtai}OzWSqtg$JAi>E_}?~R)IVKD1hgj3h+AT zf6r~>!%^P+{c}vWB^#_Qy{@o9`Npq3x(lN|D3v)hAwZtm526eMsxgOFJ9y<{WbVa4$U}eaRlkqs(dtgmX;0y?KW9HkaR>tV&5G z^@ZTmHy&(#N?#=>OjXd(ujfotA3bqh-b44Q$%D(jJ1z~@df{phmgfps-&TixD-_v= z{}UJvolptq=n>KhSf8J3b9zGeQ)yiAToF&jfor_{)xUFSQ*yQ;Uswy~lm1LSFLolx zi$uJ~s*nx;LS_QewCYw2X_nG!*tqM)JMdzqSCt2vm%KL{m}PSSlWVhuKfV_L=pgB$ zo0DBc8`}sKDHM=2=eN!C%jcNszm8EGOdAEy`0&(1F-a8h)($xyf=bRdsTF+IRovbk zX=IZ%s~%G{X#p?|qkeq5pJeD^`V`Q&pGd|jE!Luj_fPG5O1b|2`i;e^TBC}C%0WYo zJ+gIJA0hG22YseT3sY1GiGFyA73mPZQugoq;RUs|ySbiImz^Ga-YqF$ z9O5sDvRIiO>V!wr1&_eY5#|!JgPF(FcSzm&h6R|$NEf6L(mm9Nnd9`+mqx;hZ*kl4 zis%b)StOA4FQeC|^NR-+5w11u+0%D<$ol6;^}lFoVpgXuUv2S@7;85@5h2N{dj4|m z%FvI}^(H{8CC2EffyDcu(uCtjJEIgM8oTF}?xZrM+A^OAUs&QPI;0+$n&zG5byOq( zkX>PA&fEDR)wZ(>wejdL+k-GG^v|cVdPN+8Bs8eZMamdqI=x?HYI6ZjLSDHk|Gzmc zBci!hTl|i9k~!tTEjo)z{$NPB8K2%~`7=dst%paFV{IBpy{c|$RhgBZSEk8fX{^9a z1DEq2aJP&AQ6wog;0 z_NIY^KMsa&zp9rkUt6T!5@}pK0YSR)*_oN|q7$YS3Nm?Qrp1~%H8f)2nW{D(g+m0_ zI3V2Tg2Jv=6_LtQySxqWox8PIWP<;$s9EdHjFqTKH`rec%p^%f%zUTqNIK*GQJV0I zVPck89UwHR&-wL*P1d}g<;QMDtcl$8;`HT>qSLCy70E>PCC8`|@0E1f=8x=DFP@Gj zzxC)TPqk~r*=8Ipp_OoQ8L{PIu@$x&1Nhr*1_zQ#aI4vY_)=Bcx}R(wk^`dJ{`zTt z&F3FBGo*|mR@n7_DB@J4j^KCoUwKwM6{auyUArt`GqD=R8yx1=3YqwG@Ga;x_Z&Ch zB~lKpPX1kPkFH?UT7d0AHUx<7|4T8kM}~9C+3H%GwI+B0YlOC0m}!g(@49 zo}67#`}|xos9k?;&-r_6kpB8>P#_;IZnTyYuc@quyjW<_ezz8nLB3Q_xuiL zN6>APh=7uv(jo{9meQ)?Z;CI7wIvsVPS#zFckYkzonJSCrxtunWVRWNDNkJ2z}#BJ zG)r@U_&$~`$b)4$#5}z~?5C#GWb#6}F!zlsWcdMI{MlN>QtZ&mODLBRBG`E=FA_!C zpZNv2^2|wnXQz7?8%SH$R?~+`EueObzk@%t3D|<~X@&=T96=Z_CMwb2jOecH{>2uN zzUL~gaUE+|O{D?{xTm#}twd=`y57FV1gj0agbW|)uv44}AN*u$l6nn7w-7~DsTh^6 z_9y)D?#^9{v6AjMMaAlZGRf6TKMriL$}j?gs$3`rfk7?lmBE=A>(5L7nYVAxLB~pm HL&yFb=7W;V literal 0 HcmV?d00001 diff --git a/doc/logo-light.png b/doc/logo-light.png new file mode 100644 index 0000000000000000000000000000000000000000..898fcecc96fb49845d8287a89ee647b94b6af0b7 GIT binary patch literal 1448 zcmV;Z1y}lsP)002S=0{{R3xS(K~0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUyV^B;~MgRZ*Mo2!4$V;N5o^*C@;_=d{ z)_BF^rP0yP^YrtR%U1aO^ioqw=;-J1_~>0QeH zM>3D$9YcuwEF_bysbl*H)Xafgr#b?i&G84baVFi*Jj;eQqjkNwKH(#(2!YGC7wobXmwBsb#&F;ddm$CoeHL*YTlJIFbYfx z_0d+EOGnQjiq$(ejv!O#H`C2>Ly#FkVO8da$wR$<8s!?<99nd5tAiS;t@jItNU0HO z^(12!I*O~<71@QyE)vfwM}B~3hMcJ5z5V`GhX||9xta)AxCnqod}c&EfbfqtKyK6r zh(S5lG*%`J|cmDn#Q(qma zy8uWXQU|X1$XbA?>2fIMEH9<*GaqR+Hc<~6NeP94I;GL8pW#hCg)s~Dv`7j0=?kgH zDejfE0kI6zUX5s>MF>VN2Qk|AO z=7&?uyDmcvPnzO4P^)&>BK0n8maIAX1v6Z^@0F;Bd?kF4mTo-SA4$z>p7^xO_nOL? z7|qDM%`T4YvoEIZG@Csgb@rsS0b?CVr1scqHC^}y)XUN6X8_Am0B4E?>fXM`$=Gf0 z*x!H}WfVg!Wf(G2MJ>lN!-oRZ(8-+=lP zJI!0}LcJr)!o{|lKa<+*-tx+oUPyy6CRGZlD)7|%uc{!G&{8c&J=Xq1xj;4*8B#6v zRo7nTsSD4sT6hCc^VPo`R;pd(KKFSl1vTsaG}>yRFpEC+N@~7ssH=#t9_-U@?De|< z+75uuy;%$39uC#eR&Hji`h143oI|b9J+5jKv)n;Fm}|ZAe&UdU8vvpqDn&C}(bFBD zcBJjF%hXdVMcL`PIJD8U9Xo9!Ad8K?`t?j^4@22|8<$Xxu<7YTI-17TskVo6j^RDl zLA0^FYWt|o1E!6k&pM?`IvL#C*S1ouEiSXSnmX~S_M7DhMRBj^=RP{LMx)O9)}XJ6 zB4T3`TTUxT-fBB_A;tq+lE%Us^)c4W#*p(9uCi)k*Y=YsYi|Xduvx`}{lTu$*s{K0 zr?WDyGP`#IJB7r#_Zjr&+U(vL?1fG)&N`fnau(*^E%?OQ*uICqgv{K#1HawJvJwZ4 zJ|`7!o!qC)K$De=r-9oG%VF!N(f^Sze%btw00RIy6GXAOp9^gO0000cwW1%*7 z5&}w^Ku8zU2LqOYR1!>SCq99d4`5{_3U-#JNic;5d;*Io!O9|ng#-nYe_@1W*+mCF zZrRzLyPF9%#`l2};{i{oVy-7VZ5=}aVM~D=`Y57?gsaF#4lVG4sO$&PleI57btY~r z@`qO>(ZmXOxI)(WvIyz{t+F1U;zka>Ve9Bo2@?!FBQe95<*l|*`_DM@EyWB1780!v(@qK(*$7RvgDFQa|OFWSgB xE)S(&BQxO}jXFmPmq<%tHL)pvT>thjzyK!*F6VT)7##or002ovPDHLkV1i^;gYEzT literal 0 HcmV?d00001 From 5d7577c71ab535dfd5c3f29b8c15a725137ff3b8 Mon Sep 17 00:00:00 2001 From: isaacs Date: Mon, 23 Jan 2012 02:07:15 -0800 Subject: [PATCH 03/36] doctool: correct improperly nested ul/li handling --- tools/doctool/doctool.js | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/tools/doctool/doctool.js b/tools/doctool/doctool.js index 634d82c9218..ca3f60958b1 100644 --- a/tools/doctool/doctool.js +++ b/tools/doctool/doctool.js @@ -42,7 +42,11 @@ function generateToc(data) { } if (level > last_level) { - toc.push("
      "); + var c = last_level - level; + do { + toc.push("
        "); + c ++; + } while (c < -1); } else if (level < last_level) { for(var c=last_level-level; 0 < c ; c-- ) { toc.push("
      "); @@ -61,7 +65,7 @@ function generateToc(data) { toc.push("
    "); } - toc.push("
    ") + toc.push("
    ") toc.push(""); return toc.join(""); @@ -89,8 +93,14 @@ function convertData(data) { .replace(/(\([^<]+)(\<\/h[1-6]\>)/gmi, function(o, ts, c, te) { return ts+' id="'+formatIdString(c)+'">'+c+te; }) - .replace(/(\]+\>)([^<]+)(\<\/h[3-4]\>)/gmi, function(o, ts, c, te) { - return ts+c+' #'+te; + .replace(/(\]+\>)([^<]+)(\<\/h[2-4]\>)/gmi, + function(o, ts, c, te) { + var mark = ' ' + + '' + + '#'; + + return ts+c+mark+te; }); return html; From 5c0d11b12a8214110bb78639daab452ce3d252e0 Mon Sep 17 00:00:00 2001 From: isaacs Date: Mon, 23 Jan 2012 02:07:59 -0800 Subject: [PATCH 04/36] doc: Add images to makefile --- Makefile | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index db4880abfed..2a6b70b4658 100644 --- a/Makefile +++ b/Makefile @@ -91,23 +91,33 @@ website_files = \ out/doc/sh_main.js \ out/doc/sh_javascript.min.js \ out/doc/sh_vim-dark.css \ + out/doc/sh.css \ out/doc/logo.png \ - out/doc/sponsored.png \ out/doc/favicon.ico \ out/doc/pipe.css \ out/doc/about/index.html \ out/doc/close-downloads.png \ out/doc/community/index.html \ out/doc/community/not-invented-here.png \ - out/doc/download-logo.png \ - out/doc/ebay-logo.png \ - out/doc/footer-logo.png \ - out/doc/icons.png \ - out/doc/linkedin-logo.png \ out/doc/logos/index.html \ out/doc/microsoft-logo.png \ - out/doc/platform-icons.png \ out/doc/ryan-speaker.jpg \ + out/doc/download-logo.png \ + out/doc/ebay-logo.png \ + out/doc/footer-logo-alt.png \ + out/doc/footer-logo.png \ + out/doc/icons-interior.png \ + out/doc/icons.png \ + out/doc/home-icons.png \ + out/doc/joyent-logo_orange_nodeorg-01.png \ + out/doc/linkedin-logo.png \ + out/doc/logo-light.png \ + out/doc/mac_osx_nodejs_installer_logo.png \ + out/doc/microsoft-logo.png \ + out/doc/platform-icons.png \ + out/doc/sponsored.png \ + out/doc/twitter-bird.png \ + out/doc/community-icons.png \ out/doc/yahoo-logo.png doc docs: out/Release/node $(apidoc_dirs) $(website_files) $(apiassets) $(apidocs) From 6768d2fc936ea4d8786897ea9c5c415efedb5b24 Mon Sep 17 00:00:00 2001 From: isaacs Date: Mon, 23 Jan 2012 02:12:20 -0800 Subject: [PATCH 05/36] doc: Pixel-nudging --- doc/about/index.html | 6 +- doc/api_assets/style.css | 241 ++++++++++++++++++++++++--------------- doc/community/index.html | 6 +- doc/index.html | 6 +- doc/logos/index.html | 4 +- doc/pipe.css | 194 ++++++++++++++++++++----------- doc/sh.css | 23 ++++ doc/template.html | 6 +- tools/doctool/doctool.js | 3 + 9 files changed, 317 insertions(+), 172 deletions(-) create mode 100644 doc/sh.css diff --git a/doc/about/index.html b/doc/about/index.html index 549b8d6f033..5335539ff29 100644 --- a/doc/about/index.html +++ b/doc/about/index.html @@ -11,14 +11,14 @@ - + node.js - +
    @@ -127,7 +127,7 @@ console.log('Server running at http://127.0.0.1:1337/');
  • Community
  • Logos
  • Jobs
  • -
  • +
  • Copyright 2010 Joyent, Inc, Node.js is a trademark of Joyent, Inc. View license.

    diff --git a/doc/api_assets/style.css b/doc/api_assets/style.css index b5665d53b72..6068455e3f5 100644 --- a/doc/api_assets/style.css +++ b/doc/api_assets/style.css @@ -8,11 +8,11 @@ body { font-size: 14px; line-height: 180%; color: black; - margin: 0; padding: 40px 0 0 0; + margin: 0; padding: 49px 0 0 0; border-top: 6px #8CC84B solid; } a { - color: #669900; + color: #690; text-decoration: underline; } a:visited { @@ -22,7 +22,7 @@ a { a:hover, a:focus { text-decoration: none; } - + code a:hover { background: none; color: #b950b7; @@ -32,9 +32,14 @@ a { display: none; } +#gtoc p { + margin:0; + font-size:18px; + line-height: 30px; +} + #gtoc a { font-family: Georgia, FreeSerif, Times, serif; - font-size: 16px; text-decoration: none; color: #46483e; } @@ -70,6 +75,13 @@ p { text-rendering: optimizeLegibility; } +.apidoc p { + font-size: 15px; + line-height: 22px; + color: #000; + font-family: Georgia, FreeSerif, Times, serif; +} + ol, ul, dl { margin: 0 0 1em 0; padding: 0; @@ -105,7 +117,7 @@ dd + dt.pre { } h1, h2, h3, h4, h5, h6 { - font-family: Helvetica, Arial, sans-serif + font-family: Helvetica, Arial, sans-serif; color: #000; text-rendering: optimizeLegibility; position: relative; @@ -116,17 +128,23 @@ h1 { font-size: 30px; font-weight: normal; line-height: 36px; - color: #669900; + color: #690; + margin: 15px 0 11px; } h2 { - font-size: 1.9em; - line-height: 1.227em; - margin: 0 0 0.5em; + font-size: 29px; + line-height: 33px; + margin: 2em 0 15px; +} + +#toc + h2 { + margin-top:1em; + padding-top:0; } h3 { - font-size: 1.5em; + font-size: 1.4em; line-height: 1.0909em; margin: 1.5em 0 0.5em; } @@ -145,13 +163,35 @@ h4 + h4 { margin: 0 0 0.5em; } - h3 a, - h4 a { + h3, h4 { + position:relative; + padding-right:40px; + } + h2 span, h3 span, h4 span { + position:absolute; + display:block; + top:0; + right:0; + opacity: 0.3; + } + h2 span:hover, h3 span:hover, h4 span:hover { + opacity: 1; + } + h2 span a, h3 span a, h4 span a { font-size: 0.8em; - float: right; color: #000; text-decoration: none; - opacity: 0.3; + font-family: Helvetica, Arial, sans-serif; + font-weight:bold; + } + + h2 span a.top, h3 span a.top, h4 span a.top { + /* XXX Get an image and clean up these two links + * so that they look nice next to one another. + * http://www.chrisglass.com/work/nodejs/website/v05/docs.html + * -isaacs + */ + display:none; } h5 { @@ -165,7 +205,7 @@ h6 { } pre, tt, code { - font-size: 0.95em; + font-size: 14px; line-height: 1.5438em; font-family: Monaco, Consolas, "Lucida Console", monospace; margin: 0; padding: 0; @@ -204,27 +244,31 @@ code.pre { /* preload platform-icons.png */ background-image: url(platform-icons.png); background-repeat: no-repeat; - background-position: -1000px -1000px; + background-position: -999em -999em; } #intro.interior #logo { - margin-left: -130px; + margin-left: -298px; } hr { background: none; border: medium none; border-bottom: 1px solid #ccc; - margin: 2em 0 2em; + margin: 1em 0; } #toc { - + font-size:15px; + line-height:1.5em; + line-height: 22px; + padding-top:4px; } #toc h2 { - font-size: 1em; - line-height: 1.4em; + font-size: 15px; + line-height: 21px; + margin: 0 0 0.5em; } #toc h2 a { @@ -235,34 +279,28 @@ hr { margin: 1em 0 2em; } + #toc ul { + font-family: Georgia, FreeSerif, Times, serif; + } + + #toc ul a { + text-decoration:none; + border-bottom:1px dotted #690; + } + #toc ul a:hover, #toc ul a:focus { + border-bottom:1px dotted #fff; + color:#000; + } + + p tt, p code { background: #f8f8ff; border: 1px solid #dedede; padding: 0 0.2em; } -a.octothorpe { - text-decoration: none; - color: #777; - position: absolute; - top: 0; left: -1.4em; - padding: 1px 2px; - opacity: 0; - -webkit-transition: opacity 0.2s linear; -} - p:hover > a.octothorpe, - dt:hover > a.octothorpe, - dd:hover > a.octothorpe, - h1:hover > a.octothorpe, - h2:hover > a.octothorpe, - h3:hover > a.octothorpe, - h4:hover > a.octothorpe, - h5:hover > a.octothorpe, - h6:hover > a.octothorpe { - opacity: 1; - } #content { - width: 800px; + width: 953px; margin: 0 auto; overflow: visible; clear: both; @@ -270,15 +308,17 @@ a.octothorpe { } #column1.interior { - width: 590px; + width: 749px; float: right; - padding-top: 20px; + padding-top: 7px; + padding-top: 11px; + font-size:18px; } #column2.interior { - width: 160px; + width: 140px; float: left; - margin-top: -50px; + margin-top: -55px; overflow: visible; } @@ -292,44 +332,44 @@ a.octothorpe { #column2.interior li a { display: block; - padding: 0 0 0 40px; + padding: 0 0 0 35px; color: #878b78; text-transform: uppercase; text-decoration: none; - font-size: 12px; + font-size: 11px; line-height: 23px; } -#column2.interior li a.home { background: url(icons-interior.png) no-repeat -158px 3px; } -#column2.interior li a.download { background: url(icons-interior.png) no-repeat -158px -21px; } -#column2.interior li a.about { background: url(icons-interior.png) no-repeat -158px -44px; } -#column2.interior li a.npm { background: url(icons-interior.png) no-repeat -158px -70px; } -#column2.interior li a.docs { background: url(icons-interior.png) no-repeat -158px -93px; } -#column2.interior li a.blog { background: url(icons-interior.png) no-repeat -158px -117px; } -#column2.interior li a.community { background: url(icons-interior.png) no-repeat -158px -140px; } -#column2.interior li a.logos { background: url(icons-interior.png) no-repeat -158px -164px; } -#column2.interior li a.jobs { background: url(icons-interior.png) no-repeat -158px -189px; } +#column2.interior li a.home { background: url(icons-interior.png) no-repeat -156px 3px; } +#column2.interior li a.download { background: url(icons-interior.png) no-repeat -156px -21px; } +#column2.interior li a.about { background: url(icons-interior.png) no-repeat -156px -45px; } +#column2.interior li a.npm { background: url(icons-interior.png) no-repeat -156px -69px; } +#column2.interior li a.docs { background: url(icons-interior.png) no-repeat -156px -93px; } +#column2.interior li a.blog { background: url(icons-interior.png) no-repeat -156px -117px; } +#column2.interior li a.community { background: url(icons-interior.png) no-repeat -156px -141px; } +#column2.interior li a.logos { background: url(icons-interior.png) no-repeat -156px -165px; } +#column2.interior li a.jobs { background: url(icons-interior.png) no-repeat -156px -189px; } -#column2.interior li a.home.current { background-position: left 3px; } -#column2.interior li a.download.current { background-position: left -21px; } -#column2.interior li a.about.current { background-position: left -44px; } -#column2.interior li a.npm.current { background-position: left -70px; } -#column2.interior li a.docs.current { background-position: left -93px; } -#column2.interior li a.blog.current { background-position: left -117px; } -#column2.interior li a.community.current { background-position: left -140px; } -#column2.interior li a.logos.current { background-position: left -164px; } -#column2.interior li a.jobs.current { background-position: left -189px; } +#column2.interior li a.home.current { background-position: 2px 3px; } +#column2.interior li a.download.current { background-position: 2px -21px; } +#column2.interior li a.about.current { background-position: 2px -45px; } +#column2.interior li a.npm.current { background-position: 2px -69px; } +#column2.interior li a.docs.current { background-position: 2px -93px; } +#column2.interior li a.blog.current { background-position: 2px -117px; } +#column2.interior li a.community.current { background-position: 2px -141px; } +#column2.interior li a.logos.current { background-position: 2px -165px; } +#column2.interior li a.jobs.current { background-position: 2px -189px; } #column2.interior li a.current { color: #8cc84b; font-weight: bold; } -#column2.interior li a.home:hover { background-position: -333px 3px; } -#column2.interior li a.download:hover { background-position: -333px -21px; } -#column2.interior li a.about:hover { background-position: -333px -44px; } -#column2.interior li a.npm:hover { background-position: -333px -70px; } -#column2.interior li a.docs:hover { background-position: -333px -93px; } -#column2.interior li a.blog:hover { background-position: -333px -117px; } -#column2.interior li a.community:hover { background-position: -333px -140px; } -#column2.interior li a.logos:hover { background-position: -333px -164px; } -#column2.interior li a.jobs:hover { background-position: -333px -189px; } +#column2.interior li a.home:hover { background-position: -331px 3px; } +#column2.interior li a.download:hover { background-position: -331px -21px; } +#column2.interior li a.about:hover { background-position: -331px -45px; } +#column2.interior li a.npm:hover { background-position: -331px -69px; } +#column2.interior li a.docs:hover { background-position: -331px -93px; } +#column2.interior li a.blog:hover { background-position: -331px -117px; } +#column2.interior li a.community:hover { background-position: -331px -141px; } +#column2.interior li a.logos:hover { background-position: -331px -165px; } +#column2.interior li a.jobs:hover { background-position: -331px -189px; } #column2.interior li a:hover { color: #000000; text-decoration: none; } #column2.interior li + li { @@ -370,57 +410,70 @@ a.anchor { border-bottom: 1px solid #cccccc; } #footer { - width: 775px; - border-top: 1px solid #626557; - margin: 50px auto 30px auto; - padding-top: 15px; + width: 942px; + margin: 150px auto 55px auto; + padding:0; } #footer p { - color: #8BC84B; - font-size: 10px; - padding-left: 195px; - color: #878b78; + font-size: 11px; + line-height:1em; + padding: 0 0 0 195px; + color: #666; + font-family: "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Verdana, Tahoma, sans-serif; +} + +#footer a { + text-decoration:none; + border:none; + color: #690; +} +#footer a:hover { + color:#000; } #footer p a { - text-decoration: underline; + border-bottom:1px dotted #690; color: #878b78; } #footer ul { - background: url(footer-logo-alt.png) left top no-repeat; - padding-left: 195px; + background: url(footer-logo-alt.png) left 17px no-repeat; + padding: 23px 0 0 195px; height: 26px; - padding-top: 6px; - margin-left: 0; + margin-left: -1px; + border-top: 1px solid #626557; } #footer ul li { list-style-type: none; - display: block; float: left; font-size: 12px; + margin:0!important; + padding:0; + height: 12px; } #footer ul li a { margin: 0; - padding: 0; + padding: 0 6px 0 0; + display: block; + height:12px; + line-height:12px; } #footer ul li + li { - height: 12px; margin-left: 3px; } #footer ul li + li a { - padding: 0 0 0 4px; + padding: 0 6px 0 6px; border-left: 1px solid #878b78; } #footer ul li a.twitter { - background: url(twitter-bird.png) no-repeat 0 2px; - padding-left: 19px; + background: url(twitter-bird.png) no-repeat 5px 0px; + padding-left: 25px; } /* simpler clearfix */ diff --git a/doc/community/index.html b/doc/community/index.html index 13387987f41..cb93e215471 100644 --- a/doc/community/index.html +++ b/doc/community/index.html @@ -20,7 +20,7 @@ href="http://feeds.feedburner.com/nodejs/123123123"> node.js - +
    @@ -50,7 +50,7 @@

    Documentation

    -

    official API docs

    +

    Official API docs detail the node API.

    docs.nodejitsu.com answers many of the common problems people come across.

    How To Node has a growing number of useful tutorials.

    Stack Overflow node.js tag collects new information every day.

    @@ -177,7 +177,7 @@
  • Community
  • Logos
  • Jobs
  • -
  • +
  • Copyright 2010 Joyent, Inc, Node.js is a trademark of Joyent, Inc. View license.

    diff --git a/doc/index.html b/doc/index.html index 7b4bc68748a..5a6c1e003b6 100644 --- a/doc/index.html +++ b/doc/index.html @@ -18,7 +18,7 @@ href="http://feeds.feedburner.com/nodejs/123123123"> node.js - +
    @@ -31,7 +31,7 @@ Download Docs -

    v0.6.6

    +

    v0.6.8

    Node.js in the Industry

    @@ -208,7 +208,7 @@ server.listen(1337, "127.0.0.1");
  • Community
  • Logos
  • Jobs
  • -
  • +

    Copyright 2010 Joyent, Inc, Node.js is a trademark of Joyent, Inc. View license.

    diff --git a/doc/logos/index.html b/doc/logos/index.html index dab67fce599..c6681b5cb23 100644 --- a/doc/logos/index.html +++ b/doc/logos/index.html @@ -21,7 +21,7 @@ node.js - +
    @@ -82,7 +82,7 @@
  • Community
  • Logos
  • Jobs
  • -
  • +
  • Copyright Joyent, Inc., Node.js is a trademark of Joyent, Inc., View License

    diff --git a/doc/pipe.css b/doc/pipe.css index 09f0a8bb30d..999161b77b5 100644 --- a/doc/pipe.css +++ b/doc/pipe.css @@ -18,6 +18,10 @@ body.alt { color: #46483e; } +body.int { + padding-top:49px; +} + img { border: 0; } @@ -41,7 +45,7 @@ h1 { text-transform: none; color: #669900; font-weight: normal; - margin-top: 1em; + margin: 15px 0 11px; } h2 { @@ -65,7 +69,7 @@ h1 a, h2 a, h3 a, h4 a /* preload platform-icons.png */ background-image: url(platform-icons.png); background-repeat: no-repeat; - background-position: -1000px -1000px; + background-position: -999em -999em; } #intro p { @@ -77,7 +81,7 @@ h1 a, h2 a, h3 a, h4 a } #intro.interior #logo { - margin-left: -130px; + margin-left: -298px; } #intro p.version { @@ -163,13 +167,20 @@ h1 a, h2 a, h3 a, h4 a font-size: 10px; } +#quotes ul li p { + color: #D2D8BA +} + #content { - width: 800px; + width: 775px; margin: 0 auto; overflow: visible; clear: both; display: block; } +.int #content { + width: 953px; +} #column1 { width: 460px; @@ -178,6 +189,10 @@ h1 a, h2 a, h3 a, h4 a #content p { font-size: 14px; + line-height:24px; +} +#front #content p { + font-size:12px; } #content h1 + p { @@ -193,63 +208,76 @@ h1 a, h2 a, h3 a, h4 a } #column1.interior { - width: 590px; + width: 600px; float: right; - padding-top: 20px; + padding-top: 11px; + font-size:18px; + padding-right:150px; } #column2.interior { - width: 160px; + width: 140px; float: left; - margin-top: -50px; + margin-top: -54px; overflow: visible; } +#column2.interior ul { + margin-left: 0; +} + #column2.interior li { list-style-type: none; } #column2.interior li a { display: block; - padding: 1px 0px 1px 40px; + padding: 0 0 0 35px; color: #878b78; text-transform: uppercase; + text-decoration: none; + font-size: 11px; + line-height: 23px; } -#column2.interior li a.home { background: url(icons-interior.png) no-repeat -158px 3px; } -#column2.interior li a.download { background: url(icons-interior.png) no-repeat -158px -21px; } -#column2.interior li a.about { background: url(icons-interior.png) no-repeat -158px -44px; } -#column2.interior li a.npm { background: url(icons-interior.png) no-repeat -158px -70px; } -#column2.interior li a.docs { background: url(icons-interior.png) no-repeat -158px -93px; } -#column2.interior li a.blog { background: url(icons-interior.png) no-repeat -158px -117px; } -#column2.interior li a.community { background: url(icons-interior.png) no-repeat -158px -140px; } -#column2.interior li a.logos { background: url(icons-interior.png) no-repeat -158px -164px; } -#column2.interior li a.jobs { background: url(icons-interior.png) no-repeat -158px -189px; } +#column2.interior li a.home { background: url(icons-interior.png) no-repeat -156px 3px; } +#column2.interior li a.download { background: url(icons-interior.png) no-repeat -156px -21px; } +#column2.interior li a.about { background: url(icons-interior.png) no-repeat -156px -44px; } +#column2.interior li a.npm { background: url(icons-interior.png) no-repeat -156px -69px; } +#column2.interior li a.docs { background: url(icons-interior.png) no-repeat -156px -93px; } +#column2.interior li a.blog { background: url(icons-interior.png) no-repeat -156px -117px; } +#column2.interior li a.community { background: url(icons-interior.png) no-repeat -156px -141px; } +#column2.interior li a.logos { background: url(icons-interior.png) no-repeat -156px -165px; } +#column2.interior li a.jobs { background: url(icons-interior.png) no-repeat -156px -189px; } -#column2.interior li a.home.current { background-position: left 3px; } -#column2.interior li a.download.current { background-position: left -21px; } -#column2.interior li a.about.current { background-position: left -44px; } -#column2.interior li a.npm.current { background-position: left -70px; } -#column2.interior li a.docs.current { background-position: left -93px; } -#column2.interior li a.blog.current { background-position: left -117px; } -#column2.interior li a.community.current { background-position: left -140px; } -#column2.interior li a.logos.current { background-position: left -164px; } -#column2.interior li a.jobs.current { background-position: left -189px; } +#column2.interior li a.home.current { background-position: 2px 3px; } +#column2.interior li a.download.current { background-position: 2px -21px; } +#column2.interior li a.about.current { background-position: 2px -45px; } +#column2.interior li a.npm.current { background-position: 2px -69px; } +#column2.interior li a.docs.current { background-position: 2px -93px; } +#column2.interior li a.blog.current { background-position: 2px -117px; } +#column2.interior li a.community.current { background-position: 2px -141px; } +#column2.interior li a.logos.current { background-position: 2px -165px; } +#column2.interior li a.jobs.current { background-position: 2px -189px; } #column2.interior li a.current { color: #8cc84b; font-weight: bold; } -#column2.interior li a.home:hover { background-position: -333px 3px; } -#column2.interior li a.download:hover { background-position: -333px -21px; } -#column2.interior li a.about:hover { background-position: -333px -44px; } -#column2.interior li a.npm:hover { background-position: -333px -70px; } -#column2.interior li a.docs:hover { background-position: -333px -93px; } -#column2.interior li a.blog:hover { background-position: -333px -117px; } -#column2.interior li a.community:hover { background-position: -333px -140px; } -#column2.interior li a.logos:hover { background-position: -333px -164px; } -#column2.interior li a.jobs:hover { background-position: -333px -189px; } +#column2.interior li a.home:hover { background-position: -331px 3px; } +#column2.interior li a.download:hover { background-position: -331px -21px; } +#column2.interior li a.about:hover { background-position: -331px -45px; } +#column2.interior li a.npm:hover { background-position: -331px -69px; } +#column2.interior li a.docs:hover { background-position: -331px -93px; } +#column2.interior li a.blog:hover { background-position: -331px -117px; } +#column2.interior li a.community:hover { background-position: -331px -141px; } +#column2.interior li a.logos:hover { background-position: -331px -165px; } +#column2.interior li a.jobs:hover { background-position: -331px -189px; } #column2.interior li a:hover { color: #000000; text-decoration: none; } #column2.interior li + li { border-top: 1px solid #c1c7ac; + border-top:1px solid #65675c; +} +.alt #column2.interior li + li { + border-top: 1px solid #c1c7ac; } #column2.interior p.twitter { @@ -262,8 +290,8 @@ h1 a, h2 a, h3 a, h4 a } .row { - padding-top: 20px; - padding-bottom: 20px; + padding-top: 10px; + padding-bottom: 10px; } .row + .row { @@ -295,15 +323,17 @@ h1 a, h2 a, h3 a, h4 a } .block + .block { - margin-left: 30px; + margin-left: 20px; + width: 300px; } #content .block p { - font-size: 12px; + font-size: 13px; + line-height:21px; } #explore { - background: url(home-icons.png) no-repeat left 11px; + background: url(home-icons.png) no-repeat left 17px; } #explore li { @@ -340,29 +370,55 @@ h1 a, h2 a, h3 a, h4 a } #footer { - width: 775px; - border-top: 1px solid #626557; - margin: 50px auto 30px auto; - padding-top: 15px; + width: 942px; + margin: 150px auto 55px auto; + padding:0; } #footer p { - color: #8BC84B; - font-size: 10px; - padding-left: 195px; - color: #878b78; + font-size: 11px; + line-height:1em; + padding: 0 0 0 195px; + color: #666; + font-family: "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Verdana, Tahoma, sans-serif; +} + +#front #footer { + width: 775px; + margin: 50px auto 30px auto; + padding-top: 15px; +} +#front #footer ul { + margin-right:0; + padding-right:0; +} + +#footer a { + text-decoration:none; + border:none; + color: #690; +} + +#footer a:hover { + color:#000; +} +#front #footer a:hover { + color:#fff; } #footer p a { - text-decoration: underline; + border-bottom:1px dotted #690; color: #878b78; } #footer ul { - background: url(footer-logo.png) left top no-repeat; + background: url(footer-logo.png) left 17px no-repeat; + border-top: 1px solid #626557; + border-color:#90918b; + padding-top:23px; padding-left: 195px; height: 26px; - padding-top: 6px; + margin-right:137px; } .alt #footer ul { background-image: url(footer-logo-alt.png); @@ -370,28 +426,32 @@ h1 a, h2 a, h3 a, h4 a #footer ul li { list-style-type: none; - display: block; float: left; + font-size: 12px; + margin:0!important; + height: 12px; } #footer ul li a { margin: 0; - padding: 0; + padding: 0 6px 0 0; + display: block; + height:12px; + line-height:12px; } #footer ul li + li { - height: 12px; margin-left: 3px; } #footer ul li + li a { - padding: 0 0 0 4px; + padding: 0 6px 0 6px; border-left: 1px solid #878b78; } #footer ul li a.twitter { - background: url(twitter-bird.png) no-repeat 0 2px; - padding-left: 19px; + background: url(twitter-bird.png) no-repeat 5px 0px; + padding-left: 25px; } @@ -489,11 +549,17 @@ div#download ul#documentation li a { margin-bottom: 37px; } -pre, code { - font-family: Monaco, 'Andale Mono', 'Lucida Console', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif; - font-size: 12px; - color: #d2d8ba; -} + pre, tt, code { + color: #d2d8ba; + font-size: 14px; + line-height: 22px; + font-family: Monaco, Consolas, "Lucida Console", monospace; + margin: 0; padding: 0; + } + #front pre, #front tt, #front code { + font-size:12px; + line-height:22px; + } pre { padding-left: 1em; @@ -524,7 +590,7 @@ dd { a { - color: #8BC84B; + color: #690; text-decoration: none; } a:hover { text-decoration: underline; } diff --git a/doc/sh.css b/doc/sh.css new file mode 100644 index 00000000000..b9ed5a30360 --- /dev/null +++ b/doc/sh.css @@ -0,0 +1,23 @@ +.sh_sourceCode { + font-weight: normal; + font-style: normal; +} + +.sh_sourceCode .sh_symbol , .sh_sourceCode .sh_cbracket { + color: #333; +} + +.sh_sourceCode .sh_keyword { + color: #c96; +} + +.sh_sourceCode .sh_string, .sh_sourceCode .sh_regexp, .sh_sourceCode .sh_number, +.sh_sourceCode .sh_specialchar +{ + color: #690; +} + +.sh_sourceCode .sh_comment { + color: #666; +} + diff --git a/doc/template.html b/doc/template.html index 3af3fefe8cb..ccff0f27fe9 100644 --- a/doc/template.html +++ b/doc/template.html @@ -7,7 +7,7 @@ - +
    @@ -31,7 +31,7 @@
    -

    Node.js v0.6.7 Manual & Documentation

    +

    Node.js v0.6.8 Manual & Documentation

    @@ -51,7 +51,7 @@
  • Community
  • Logos
  • Jobs
  • -
  • +
  • Copyright 2010 Joyent, Inc, Node.js is a trademark of Joyent, Inc. View license.

    diff --git a/tools/doctool/doctool.js b/tools/doctool/doctool.js index ca3f60958b1..85acad2a367 100644 --- a/tools/doctool/doctool.js +++ b/tools/doctool/doctool.js @@ -129,6 +129,9 @@ if (argc > 3) { output = output.replace("{{section}}", filename+" - ") } else { + if (filename === "index") { + html = '
    ' + html + '
    '; + } output = output.replace("{{section}}", ""); output = output.replace(/]*)>/, ''); } From 7b93eb0000aa7f63d9e26e3ad5c390ca9c4aa033 Mon Sep 17 00:00:00 2001 From: isaacs Date: Mon, 23 Jan 2012 13:50:31 -0800 Subject: [PATCH 06/36] doc: Remove default border around logo for MSIE --- doc/api_assets/style.css | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/api_assets/style.css b/doc/api_assets/style.css index 6068455e3f5..0ade5b2231f 100644 --- a/doc/api_assets/style.css +++ b/doc/api_assets/style.css @@ -249,6 +249,7 @@ code.pre { #intro.interior #logo { margin-left: -298px; + border:0; } hr { From f33a35e293fb51dc5644d514b154564ad330baa4 Mon Sep 17 00:00:00 2001 From: isaacs Date: Mon, 23 Jan 2012 13:53:11 -0800 Subject: [PATCH 07/36] doc: trademark link must be absolute --- doc/about/index.html | 2 +- doc/community/index.html | 2 +- doc/index.html | 2 +- doc/logos/index.html | 2 +- doc/template.html | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/about/index.html b/doc/about/index.html index 5335539ff29..255b0f8bff3 100644 --- a/doc/about/index.html +++ b/doc/about/index.html @@ -130,7 +130,7 @@ console.log('Server running at http://127.0.0.1:1337/');
  • -

    Copyright 2010 Joyent, Inc, Node.js is a trademark of Joyent, Inc. View license.

    +

    Copyright 2010 Joyent, Inc, Node.js is a trademark of Joyent, Inc. View license.

    diff --git a/doc/community/index.html b/doc/community/index.html index cb93e215471..4fad90e815a 100644 --- a/doc/community/index.html +++ b/doc/community/index.html @@ -180,7 +180,7 @@
  • -

    Copyright 2010 Joyent, Inc, Node.js is a trademark of Joyent, Inc. View license.

    +

    Copyright 2010 Joyent, Inc, Node.js is a trademark of Joyent, Inc. View license.

    From ed111975a096cb44a7d737e46c6e0c73025e0670 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Mon, 23 Jan 2012 21:09:56 +0100 Subject: [PATCH 08/36] dgram: make setMulticastTTL() conform to v0.4 API - throw if the ttl argument is not a number - return the ttl argument (not particulary useful but it's what v0.4 did) Note that the 0 < ttl < 256 check has *not* been reinstated. On Linux, -1 is a valid argument to setsockopt(IPPROTO_IP, IP_TTL). --- lib/dgram.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/dgram.js b/lib/dgram.js index d5c2e0da69c..4166b026e1b 100644 --- a/lib/dgram.js +++ b/lib/dgram.js @@ -237,11 +237,15 @@ Socket.prototype.setTTL = function(arg) { Socket.prototype.setMulticastTTL = function(arg) { - if (this._handle.setMulticastTTL(arg) == -1) { + if (typeof arg !== 'number') { + throw new TypeError('Argument must be a number'); + } + + if (this._handle.setMulticastTTL(arg)) { throw errnoException(errno, 'setMulticastTTL'); } - return true; + return arg; }; From fc6a9673c8ec6e22565bb5a837f33b845e5127ce Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Mon, 23 Jan 2012 21:28:30 +0100 Subject: [PATCH 09/36] dgram: make setBroadcast() conform to v0.4 API - don't return a value --- lib/dgram.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/dgram.js b/lib/dgram.js index 4166b026e1b..2e8071ca121 100644 --- a/lib/dgram.js +++ b/lib/dgram.js @@ -223,11 +223,9 @@ Socket.prototype.address = function() { Socket.prototype.setBroadcast = function(arg) { - if (this._handle.setBroadcast((arg) ? 1 : 0) == -1) { - throw errnoException(errno, 'setBroadcast'); + if (this._handle.setBroadcast((arg) ? 1 : 0)) { + throw errnoException(errno, 'setBroadcast'); } - - return true; }; From 6999fb3d1e342cc5bcd41c5ff41ff0c88ddfb250 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Mon, 23 Jan 2012 21:36:48 +0100 Subject: [PATCH 10/36] dgram: make addMembership() and dropMembership() conform to v0.4 API - throw on error, don't return an error code --- lib/dgram.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/dgram.js b/lib/dgram.js index 2e8071ca121..ee239558199 100644 --- a/lib/dgram.js +++ b/lib/dgram.js @@ -260,7 +260,9 @@ Socket.prototype.addMembership = function(multicastAddress, throw new Error('multicast address must be specified'); } - return this._handle.addMembership(multicastAddress, interfaceAddress); + if (this._handle.addMembership(multicastAddress, interfaceAddress)) { + throw new errnoException(errno, 'addMembership'); + } }; @@ -272,7 +274,9 @@ Socket.prototype.dropMembership = function(multicastAddress, throw new Error('multicast address must be specified'); } - return this._handle.dropMembership(multicastAddress, interfaceAddress); + if (this._handle.dropMembership(multicastAddress, interfaceAddress)) { + throw new errnoException(errno, 'dropMembership'); + } }; From 9037decb28e324b78a310d2557dc12c177cbaee1 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Tue, 24 Jan 2012 00:04:45 +0100 Subject: [PATCH 11/36] test: remove erroneous dropMembership() call The socket is not part of any multicast group. Bug wasn't visible until 6999fb3. --- test/simple/test-dgram-broadcast-multi-process.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/simple/test-dgram-broadcast-multi-process.js b/test/simple/test-dgram-broadcast-multi-process.js index d0a98aa1cf3..10b1171bfa9 100644 --- a/test/simple/test-dgram-broadcast-multi-process.js +++ b/test/simple/test-dgram-broadcast-multi-process.js @@ -140,9 +140,7 @@ if (!cluster.isMaster) { process.send({ message : buf.toString() }); if (receivedMessages.length == messages.length) { - listenSocket.dropMembership(LOCAL_BROADCAST_HOST); - process.nextTick(function() { // TODO should be changed to below. - // listenSocket.dropMembership(LOCAL_BROADCAST_HOST, function() { + process.nextTick(function() { listenSocket.close(); }); } From aef62a03ee27ffb149950df5caccc2b4965169d8 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Mon, 23 Jan 2012 22:39:07 +0100 Subject: [PATCH 12/36] test: join multicast group *after* binding --- test/simple/test-dgram-multicast-multi-process.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/simple/test-dgram-multicast-multi-process.js b/test/simple/test-dgram-multicast-multi-process.js index 784bb6c0943..79df7a9e561 100644 --- a/test/simple/test-dgram-multicast-multi-process.js +++ b/test/simple/test-dgram-multicast-multi-process.js @@ -129,8 +129,6 @@ if (!cluster.isMaster) { var receivedMessages = []; var listenSocket = dgram.createSocket('udp4'); - listenSocket.addMembership(LOCAL_BROADCAST_HOST); - listenSocket.on('message', function(buf, rinfo) { console.error('%s received %s from %j', process.pid ,util.inspect(buf.toString()), rinfo); @@ -157,4 +155,6 @@ if (!cluster.isMaster) { }); listenSocket.bind(common.PORT); + + listenSocket.addMembership(LOCAL_BROADCAST_HOST); } From 57ddf5f50ae3c7e3fe463da9a36c3e0bd615519c Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Mon, 23 Jan 2012 22:38:22 +0100 Subject: [PATCH 13/36] test: fix typos in error messages --- test/simple/test-dgram-multicast-multi-process.js | 2 +- test/simple/test-dgram-multicast-setTTL.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/simple/test-dgram-multicast-multi-process.js b/test/simple/test-dgram-multicast-multi-process.js index 79df7a9e561..65d9dfc61c6 100644 --- a/test/simple/test-dgram-multicast-multi-process.js +++ b/test/simple/test-dgram-multicast-multi-process.js @@ -85,7 +85,7 @@ if (cluster.isMaster) { } }); - console.error('%d received %d matching messges.', worker.pid + console.error('%d received %d matching messages.', worker.pid , count); assert.equal(count, messages.length diff --git a/test/simple/test-dgram-multicast-setTTL.js b/test/simple/test-dgram-multicast-setTTL.js index a2207a78d00..cb870efdcf6 100644 --- a/test/simple/test-dgram-multicast-setTTL.js +++ b/test/simple/test-dgram-multicast-setTTL.js @@ -35,7 +35,7 @@ try { thrown = true; } -assert(thrown, 'Setting an invalid mutlicast TTL should throw some error'); +assert(thrown, 'Setting an invalid multicast TTL should throw some error'); //close the socket -socket.close(); \ No newline at end of file +socket.close(); From 986e61255736a74fad1d96cc928f049c93734e05 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Mon, 23 Jan 2012 22:39:49 +0100 Subject: [PATCH 14/36] uv: upgrade to b88bc43 --- deps/uv/include/uv.h | 34 +++++++++++++++++++++++++++++++--- deps/uv/src/unix/error.c | 1 + deps/uv/src/unix/udp.c | 30 ++++++++++++++---------------- deps/uv/src/win/error.c | 1 + deps/uv/src/win/tty.c | 30 +++++++++++++++++++++++++++--- deps/uv/src/win/udp.c | 12 ++++++++++++ deps/uv/test/test-fs.c | 36 +++++++++++++++++++++++++++++++++++- deps/uv/test/test-list.h | 2 ++ 8 files changed, 123 insertions(+), 23 deletions(-) diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h index fb4e40ab4cc..629435274ef 100644 --- a/deps/uv/include/uv.h +++ b/deps/uv/include/uv.h @@ -115,7 +115,8 @@ typedef intptr_t ssize_t; XX( 45, EAISOCKTYPE, "") \ XX( 46, ESHUTDOWN, "") \ XX( 47, EEXIST, "file already exists") \ - XX( 48, ESRCH, "no such process") + XX( 48, ESRCH, "no such process") \ + XX( 49, ENAMETOOLONG, "name too long") #define UV_ERRNO_GEN(val, name, s) UV_##name = val, @@ -631,6 +632,20 @@ UV_EXTERN int uv_udp_set_membership(uv_udp_t* handle, const char* multicast_addr, const char* interface_addr, uv_membership membership); +/* + * Set IP multicast loop flag. Makes multicast packets loop back to + * local sockets. + * + * Arguments: + * handle UDP handle. Should have been initialized with + * `uv_udp_init`. + * on 1 for on, 0 for off + * + * Returns: + * 0 on success, -1 on error. + */ +UV_EXTERN int uv_udp_set_multicast_loop(uv_udp_t* handle, int on); + /* * Set the multicast ttl * @@ -642,7 +657,7 @@ UV_EXTERN int uv_udp_set_membership(uv_udp_t* handle, * Returns: * 0 on success, -1 on error. */ -int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl); +UV_EXTERN int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl); /* * Set broadcast on or off @@ -655,7 +670,20 @@ int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl); * Returns: * 0 on success, -1 on error. */ -int uv_udp_set_broadcast(uv_udp_t* handle, int on); +UV_EXTERN int uv_udp_set_broadcast(uv_udp_t* handle, int on); + +/* + * Set the time to live + * + * Arguments: + * handle UDP handle. Should have been initialized with + * `uv_udp_init`. + * ttl 1 through 255 + * + * Returns: + * 0 on success, -1 on error. + */ +UV_EXTERN int uv_udp_set_ttl(uv_udp_t* handle, int ttl); /* * Send data. If the socket has not previously been bound with `uv_udp_bind` diff --git a/deps/uv/src/unix/error.c b/deps/uv/src/unix/error.c index e904d390333..80d3270db06 100644 --- a/deps/uv/src/unix/error.c +++ b/deps/uv/src/unix/error.c @@ -71,6 +71,7 @@ uv_err_code uv_translate_sys_error(int sys_errno) { case EFAULT: return UV_EFAULT; case EMFILE: return UV_EMFILE; case EMSGSIZE: return UV_EMSGSIZE; + case ENAMETOOLONG: return UV_ENAMETOOLONG; case EINVAL: return UV_EINVAL; case ECONNREFUSED: return UV_ECONNREFUSED; case EADDRINUSE: return UV_EADDRINUSE; diff --git a/deps/uv/src/unix/udp.c b/deps/uv/src/unix/udp.c index 0ebfe7079cc..3e5de929485 100644 --- a/deps/uv/src/unix/udp.c +++ b/deps/uv/src/unix/udp.c @@ -509,27 +509,25 @@ int uv_udp_set_membership(uv_udp_t* handle, const char* multicast_addr, return 0; } -int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl) { - if (setsockopt(handle->fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof ttl) == -1) { - uv__set_sys_error(handle->loop, errno); - return -1; + +#define X(name, level, option) \ + int uv_udp_set_##name(uv_udp_t* handle, int flag) { \ + if (setsockopt(handle->fd, level, option, &flag, sizeof(flag))) { \ + uv__set_sys_error(handle->loop, errno); \ + return -1; \ + } \ + return 0; \ } - return 0; -} +X(multicast_loop, IPPROTO_IP, IP_MULTICAST_LOOP) +X(multicast_ttl, IPPROTO_IP, IP_MULTICAST_TTL) +X(broadcast, SOL_SOCKET, SO_BROADCAST) +X(ttl, IPPROTO_IP, IP_TTL) -int uv_udp_set_broadcast(uv_udp_t* handle, int on) { - if (setsockopt(handle->fd, SOL_SOCKET, SO_BROADCAST, &on, sizeof on) == -1) { - uv__set_sys_error(handle->loop, errno); - return -1; - } - - return 0; -} +#undef X -int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name, - int* namelen) { +int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name, int* namelen) { socklen_t socklen; int saved_errno; int rv = 0; diff --git a/deps/uv/src/win/error.c b/deps/uv/src/win/error.c index 12ce4d1b5d7..59c9ea83461 100644 --- a/deps/uv/src/win/error.c +++ b/deps/uv/src/win/error.c @@ -94,6 +94,7 @@ uv_err_code uv_translate_sys_error(int sys_errno) { case WSAEMSGSIZE: return UV_EMSGSIZE; case ERROR_NETWORK_UNREACHABLE: return UV_ENETUNREACH; case WSAENETUNREACH: return UV_ENETUNREACH; + case WSAENOBUFS: return UV_ENOBUFS; case ERROR_OUTOFMEMORY: return UV_ENOMEM; case ERROR_NOT_CONNECTED: return UV_ENOTCONN; case WSAENOTCONN: return UV_ENOTCONN; diff --git a/deps/uv/src/win/tty.c b/deps/uv/src/win/tty.c index 88c68954c93..e61fc7e28e4 100644 --- a/deps/uv/src/win/tty.c +++ b/deps/uv/src/win/tty.c @@ -1069,12 +1069,25 @@ static int uv_tty_set_style(uv_tty_t* handle, DWORD* error) { bg_bright = 0; } else if (arg == 1) { - /* Bright */ + /* Foreground bright on */ fg_bright = 1; - } else if (arg == 21 || arg == 22) { - /* Bright off. */ + } else if (arg == 2) { + /* Both bright off */ fg_bright = 0; + bg_bright = 0; + + } else if (arg == 5) { + /* Background bright on */ + bg_bright = 1; + + } else if (arg == 21 || arg == 22) { + /* Foreground bright off */ + fg_bright = 0; + + } else if (arg == 25) { + /* Background bright off */ + bg_bright = 0; } else if (arg >= 30 && arg <= 37) { /* Set foreground color */ @@ -1091,6 +1104,17 @@ static int uv_tty_set_style(uv_tty_t* handle, DWORD* error) { } else if (arg == 49) { /* Default background color */ bg_color = 0; + + } else if (arg >= 90 && arg <= 97) { + /* Set bold foreground color */ + fg_bright = 1; + fg_color = arg - 90; + + } else if (arg >= 100 && arg <= 107) { + /* Set bold background color */ + bg_bright = 1; + bg_color = arg - 100; + } } diff --git a/deps/uv/src/win/udp.c b/deps/uv/src/win/udp.c index 8a36396b473..0a9990a5b75 100644 --- a/deps/uv/src/win/udp.c +++ b/deps/uv/src/win/udp.c @@ -579,6 +579,12 @@ void uv_process_udp_send_req(uv_loop_t* loop, uv_udp_t* handle, } +int uv_udp_set_multicast_loop(uv_udp_t* handle, int on) { + uv__set_artificial_error(handle->loop, UV_ENOSYS); + return -1; +} + + int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl) { if (setsockopt(handle->socket, IPPROTO_IP, IP_MULTICAST_TTL, (const char*)&ttl, sizeof ttl) == -1) { @@ -599,3 +605,9 @@ int uv_udp_set_broadcast(uv_udp_t* handle, int on) { return 0; } + + +int uv_udp_set_ttl(uv_udp_t* handle, int ttl) { + uv__set_artificial_error(handle->loop, UV_ENOSYS); + return -1; +} diff --git a/deps/uv/test/test-fs.c b/deps/uv/test/test-fs.c index 763af8a78de..b8e0ee65678 100644 --- a/deps/uv/test/test-fs.c +++ b/deps/uv/test/test-fs.c @@ -45,6 +45,7 @@ # define close _close #endif +#define TOO_LONG_NAME_LENGTH 8192 typedef struct { const char* path; @@ -416,6 +417,14 @@ static void open_noent_cb(uv_fs_t* req) { uv_fs_req_cleanup(req); } +static void open_nametoolong_cb(uv_fs_t* req) { + ASSERT(req->fs_type == UV_FS_OPEN); + ASSERT(req->errorno == UV_ENAMETOOLONG); + ASSERT(req->result == -1); + open_cb_count++; + uv_fs_req_cleanup(req); +} + TEST_IMPL(fs_file_noent) { uv_fs_t req; @@ -441,6 +450,31 @@ TEST_IMPL(fs_file_noent) { return 0; } +TEST_IMPL(fs_file_nametoolong) { + uv_fs_t req; + int r; + + loop = uv_default_loop(); + + char name[TOO_LONG_NAME_LENGTH + 1]; + memset(name, 'a', TOO_LONG_NAME_LENGTH); + name[TOO_LONG_NAME_LENGTH] = 0; + + r = uv_fs_open(loop, &req, name, O_RDONLY, 0, NULL); + ASSERT(r == -1); + ASSERT(req.result == -1); + ASSERT(uv_last_error(loop).code == UV_ENAMETOOLONG); + uv_fs_req_cleanup(&req); + + r = uv_fs_open(loop, &req, name, O_RDONLY, 0, open_nametoolong_cb); + ASSERT(r == 0); + + ASSERT(open_cb_count == 0); + uv_run(loop); + ASSERT(open_cb_count == 1); + + return 0; +} static void check_utime(const char* path, double atime, double mtime) { struct stat* s; @@ -1543,4 +1577,4 @@ TEST_IMPL(fs_rename_to_existing_file) { unlink("test_file2"); return 0; -} \ No newline at end of file +} diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h index 5ff162301f0..fa9390f9c75 100644 --- a/deps/uv/test/test-list.h +++ b/deps/uv/test/test-list.h @@ -103,6 +103,7 @@ TEST_DECLARE (spawn_and_kill) TEST_DECLARE (spawn_and_ping) TEST_DECLARE (kill) TEST_DECLARE (fs_file_noent) +TEST_DECLARE (fs_file_nametoolong) TEST_DECLARE (fs_file_async) TEST_DECLARE (fs_file_sync) TEST_DECLARE (fs_async_dir) @@ -269,6 +270,7 @@ TASK_LIST_START #endif TEST_ENTRY (fs_file_noent) + TEST_ENTRY (fs_file_nametoolong) TEST_ENTRY (fs_file_async) TEST_ENTRY (fs_file_sync) TEST_ENTRY (fs_async_dir) From 46e86aa80348dd8e31ade16a3b19eeee6baee0de Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Mon, 23 Jan 2012 23:38:25 +0100 Subject: [PATCH 15/36] dgram: bring back setMulticastLoopback() --- lib/dgram.js | 8 +++++++- src/udp_wrap.cc | 20 +++++++++++++++++++ .../test-dgram-multicast-multi-process.js | 9 ++++++--- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/lib/dgram.js b/lib/dgram.js index ee239558199..8c2ec6fcea6 100644 --- a/lib/dgram.js +++ b/lib/dgram.js @@ -248,7 +248,13 @@ Socket.prototype.setMulticastTTL = function(arg) { Socket.prototype.setMulticastLoopback = function(arg) { - throw new Error('not yet implemented'); + arg = arg ? 1 : 0; + + if (this._handle.setMulticastLoopback(arg)) { + throw errnoException(errno, 'setMulticastLoopback'); + } + + return arg; // 0.4 compatibility }; diff --git a/src/udp_wrap.cc b/src/udp_wrap.cc index e1be2d92da1..99d5936b6dd 100644 --- a/src/udp_wrap.cc +++ b/src/udp_wrap.cc @@ -94,6 +94,7 @@ public: static Handle AddMembership(const Arguments& args); static Handle DropMembership(const Arguments& args); static Handle SetMulticastTTL(const Arguments& args); + static Handle SetMulticastLoopback(const Arguments& args); static Handle SetBroadcast(const Arguments& args); private: @@ -156,6 +157,7 @@ void UDPWrap::Initialize(Handle target) { NODE_SET_PROTOTYPE_METHOD(t, "addMembership", AddMembership); NODE_SET_PROTOTYPE_METHOD(t, "dropMembership", DropMembership); NODE_SET_PROTOTYPE_METHOD(t, "setMulticastTTL", SetMulticastTTL); + NODE_SET_PROTOTYPE_METHOD(t, "setMulticastLoopback", SetMulticastLoopback); NODE_SET_PROTOTYPE_METHOD(t, "setBroadcast", SetBroadcast); target->Set(String::NewSymbol("UDP"), @@ -262,6 +264,7 @@ Handle UDPWrap::DropMembership(const Arguments& args) { return SetMembership(args, UV_LEAVE_GROUP); } + Handle UDPWrap::SetMulticastTTL(const Arguments& args) { HandleScope scope; UNWRAP @@ -277,6 +280,23 @@ Handle UDPWrap::SetMulticastTTL(const Arguments& args) { return scope.Close(Integer::New(r)); } + +Handle UDPWrap::SetMulticastLoopback(const Arguments& args) { + HandleScope scope; + UNWRAP + + assert(args.Length() == 1); + + int on = args[0]->Int32Value(); + int r = uv_udp_set_multicast_loop(&wrap->handle_, on); + + if (r) + SetErrno(uv_last_error(uv_default_loop())); + + return scope.Close(Integer::New(r)); +} + + Handle UDPWrap::DoSend(const Arguments& args, int family) { HandleScope scope; int r; diff --git a/test/simple/test-dgram-multicast-multi-process.js b/test/simple/test-dgram-multicast-multi-process.js index 65d9dfc61c6..75fba18ae22 100644 --- a/test/simple/test-dgram-multicast-multi-process.js +++ b/test/simple/test-dgram-multicast-multi-process.js @@ -98,10 +98,13 @@ if (cluster.isMaster) { } var sendSocket = dgram.createSocket('udp4'); + sendSocket.bind(); // FIXME a libuv limitation makes it necessary to bind() + // before calling any of the set*() functions - the bind() + // call is what creates the actual socket... - //sendSocket.setBroadcast(true); - //sendSocket.setMulticastTTL(1); - //sendSocket.setMulticastLoopback(true); + sendSocket.setBroadcast(true); + sendSocket.setMulticastTTL(1); + sendSocket.setMulticastLoopback(true); sendSocket.on('close', function() { console.error('sendSocket closed'); From 2775c0e97ebdeed64743e4f56741118fdcfd8dda Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Mon, 23 Jan 2012 23:52:08 +0100 Subject: [PATCH 16/36] dgram: bring back setTTL() --- lib/dgram.js | 10 +++- src/udp_wrap.cc | 59 ++++++------------- .../test-dgram-multicast-multi-process.js | 1 + 3 files changed, 27 insertions(+), 43 deletions(-) diff --git a/lib/dgram.js b/lib/dgram.js index 8c2ec6fcea6..b5b0473de83 100644 --- a/lib/dgram.js +++ b/lib/dgram.js @@ -230,7 +230,15 @@ Socket.prototype.setBroadcast = function(arg) { Socket.prototype.setTTL = function(arg) { - throw new Error('not yet implemented'); + if (typeof arg !== 'number') { + throw new TypeError('Argument must be a number'); + } + + if (this._handle.setTTL(arg)) { + throw errnoException(errno, 'setTTL'); + } + + return arg; }; diff --git a/src/udp_wrap.cc b/src/udp_wrap.cc index 99d5936b6dd..07d8d3143c8 100644 --- a/src/udp_wrap.cc +++ b/src/udp_wrap.cc @@ -96,6 +96,7 @@ public: static Handle SetMulticastTTL(const Arguments& args); static Handle SetMulticastLoopback(const Arguments& args); static Handle SetBroadcast(const Arguments& args); + static Handle SetTTL(const Arguments& args); private: static inline char* NewSlab(v8::Handle global, v8::Handle wrap_obj); @@ -159,6 +160,7 @@ void UDPWrap::Initialize(Handle target) { NODE_SET_PROTOTYPE_METHOD(t, "setMulticastTTL", SetMulticastTTL); NODE_SET_PROTOTYPE_METHOD(t, "setMulticastLoopback", SetMulticastLoopback); NODE_SET_PROTOTYPE_METHOD(t, "setBroadcast", SetBroadcast); + NODE_SET_PROTOTYPE_METHOD(t, "setTTL", SetTTL); target->Set(String::NewSymbol("UDP"), Persistent::New(t)->GetFunction()); @@ -215,20 +217,25 @@ Handle UDPWrap::Bind6(const Arguments& args) { return DoBind(args, AF_INET6); } -Handle UDPWrap::SetBroadcast(const Arguments& args) { - HandleScope scope; - UNWRAP - assert(args.Length() == 1); +#define X(name, fn) \ + Handle UDPWrap::name(const Arguments& args) { \ + HandleScope scope; \ + UNWRAP \ + assert(args.Length() == 1); \ + int flag = args[0]->Int32Value(); \ + int r = fn(&wrap->handle_, flag); \ + if (r) SetErrno(uv_last_error(uv_default_loop())); \ + return scope.Close(Integer::New(r)); \ + } - int on = args[0]->Uint32Value(); - int r = uv_udp_set_broadcast(&wrap->handle_, on); +X(SetTTL, uv_udp_set_ttl) +X(SetBroadcast, uv_udp_set_broadcast) +X(SetMulticastTTL, uv_udp_set_multicast_ttl) +X(SetMulticastLoopback, uv_udp_set_multicast_loop) - if (r) - SetErrno(uv_last_error(uv_default_loop())); +#undef X - return scope.Close(Integer::New(r)); -} Handle UDPWrap::SetMembership(const Arguments& args, uv_membership membership) { @@ -265,38 +272,6 @@ Handle UDPWrap::DropMembership(const Arguments& args) { } -Handle UDPWrap::SetMulticastTTL(const Arguments& args) { - HandleScope scope; - UNWRAP - - assert(args.Length() == 1); - - int ttl = args[0]->Uint32Value(); - int r = uv_udp_set_multicast_ttl(&wrap->handle_, ttl); - - if (r) - SetErrno(uv_last_error(uv_default_loop())); - - return scope.Close(Integer::New(r)); -} - - -Handle UDPWrap::SetMulticastLoopback(const Arguments& args) { - HandleScope scope; - UNWRAP - - assert(args.Length() == 1); - - int on = args[0]->Int32Value(); - int r = uv_udp_set_multicast_loop(&wrap->handle_, on); - - if (r) - SetErrno(uv_last_error(uv_default_loop())); - - return scope.Close(Integer::New(r)); -} - - Handle UDPWrap::DoSend(const Arguments& args, int family) { HandleScope scope; int r; diff --git a/test/simple/test-dgram-multicast-multi-process.js b/test/simple/test-dgram-multicast-multi-process.js index 75fba18ae22..a473e71cbd7 100644 --- a/test/simple/test-dgram-multicast-multi-process.js +++ b/test/simple/test-dgram-multicast-multi-process.js @@ -102,6 +102,7 @@ if (cluster.isMaster) { // before calling any of the set*() functions - the bind() // call is what creates the actual socket... + sendSocket.setTTL(1); sendSocket.setBroadcast(true); sendSocket.setMulticastTTL(1); sendSocket.setMulticastLoopback(true); From ccf7b41a69a8037f721a3eb495c2a82a53613634 Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Tue, 24 Jan 2012 22:45:34 +0600 Subject: [PATCH 17/36] module: fix --debug-brk on symlinked scripts * fixes #1519 --- lib/module.js | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/lib/module.js b/lib/module.js index a5963545b8d..da67ef65d26 100644 --- a/lib/module.js +++ b/lib/module.js @@ -358,6 +358,11 @@ Module.prototype.require = function(path) { }; +// Resolved path to process.argv[1] will be lazily placed here +// (needed for setting breakpoint when called with --debug-brk) +var resolvedArgv; + + // Returns exception if any Module.prototype._compile = function(content, filename) { var self = this; @@ -425,8 +430,15 @@ Module.prototype._compile = function(content, filename) { var wrapper = Module.wrap(content); var compiledWrapper = runInThisContext(wrapper, filename, true); - if (filename === process.argv[1] && global.v8debug) { - global.v8debug.Debug.setBreakPoint(compiledWrapper, 0, 0); + if (global.v8debug) { + if (!resolvedArgv) { + resolvedArgv = Module._resolveFilename(process.argv[1], null)[1]; + } + + // Set breakpoint on module start + if (filename === resolvedArgv) { + global.v8debug.Debug.setBreakPoint(compiledWrapper, 0, 0); + } } var args = [self.exports, require, self, filename, dirname]; return compiledWrapper.apply(self.exports, args); From 352febe2519b0bb0e004086fa06a27217bdbebbb Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Fri, 27 Jan 2012 00:53:37 +0100 Subject: [PATCH 18/36] uv: upgrade to 9c76d0d --- deps/uv/src/unix/udp.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/deps/uv/src/unix/udp.c b/deps/uv/src/unix/udp.c index 3e5de929485..6db0ea1063b 100644 --- a/deps/uv/src/unix/udp.c +++ b/deps/uv/src/unix/udp.c @@ -340,6 +340,14 @@ static int uv__bind(uv_udp_t* handle, goto out; } +#ifdef SO_REUSEPORT /* Apple's version of SO_REUSEADDR... */ + yes = 1; + if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof yes) == -1) { + uv__set_sys_error(handle->loop, errno); + goto out; + } +#endif + if (flags & UV_UDP_IPV6ONLY) { #ifdef IPV6_V6ONLY yes = 1; From 5c0f039c9ca9f36dfc05b5d38d8a20343d02f9f0 Mon Sep 17 00:00:00 2001 From: isaacs Date: Thu, 26 Jan 2012 12:25:51 -0800 Subject: [PATCH 19/36] Update npm to 1.1.0-3 --- deps/npm/html/api/bin.html | 2 +- deps/npm/html/api/bugs.html | 2 +- deps/npm/html/api/commands.html | 2 +- deps/npm/html/api/config.html | 2 +- deps/npm/html/api/deprecate.html | 2 +- deps/npm/html/api/docs.html | 2 +- deps/npm/html/api/edit.html | 2 +- deps/npm/html/api/explore.html | 2 +- deps/npm/html/api/help-search.html | 2 +- deps/npm/html/api/init.html | 2 +- deps/npm/html/api/install.html | 2 +- deps/npm/html/api/link.html | 2 +- deps/npm/html/api/load.html | 2 +- deps/npm/html/api/ls.html | 2 +- deps/npm/html/api/npm.html | 4 ++-- deps/npm/html/api/outdated.html | 2 +- deps/npm/html/api/owner.html | 2 +- deps/npm/html/api/pack.html | 2 +- deps/npm/html/api/prefix.html | 2 +- deps/npm/html/api/prune.html | 2 +- deps/npm/html/api/publish.html | 2 +- deps/npm/html/api/rebuild.html | 2 +- deps/npm/html/api/restart.html | 2 +- deps/npm/html/api/root.html | 2 +- deps/npm/html/api/run-script.html | 2 +- deps/npm/html/api/search.html | 2 +- deps/npm/html/api/start.html | 2 +- deps/npm/html/api/stop.html | 2 +- deps/npm/html/api/submodule.html | 2 +- deps/npm/html/api/tag.html | 2 +- deps/npm/html/api/test.html | 2 +- deps/npm/html/api/uninstall.html | 2 +- deps/npm/html/api/unpublish.html | 2 +- deps/npm/html/api/update.html | 2 +- deps/npm/html/api/version.html | 2 +- deps/npm/html/api/view.html | 2 +- deps/npm/html/api/whoami.html | 2 +- deps/npm/html/doc/README.html | 2 +- deps/npm/html/doc/adduser.html | 2 +- deps/npm/html/doc/bin.html | 2 +- deps/npm/html/doc/bugs.html | 2 +- deps/npm/html/doc/build.html | 2 +- deps/npm/html/doc/bundle.html | 2 +- deps/npm/html/doc/cache.html | 2 +- deps/npm/html/doc/changelog.html | 2 +- deps/npm/html/doc/coding-style.html | 2 +- deps/npm/html/doc/completion.html | 2 +- deps/npm/html/doc/config.html | 2 +- deps/npm/html/doc/deprecate.html | 2 +- deps/npm/html/doc/developers.html | 2 +- deps/npm/html/doc/disputes.html | 2 +- deps/npm/html/doc/docs.html | 2 +- deps/npm/html/doc/edit.html | 2 +- deps/npm/html/doc/explore.html | 2 +- deps/npm/html/doc/faq.html | 2 +- deps/npm/html/doc/folders.html | 2 +- deps/npm/html/doc/help-search.html | 2 +- deps/npm/html/doc/help.html | 2 +- deps/npm/html/doc/index.html | 2 +- deps/npm/html/doc/init.html | 2 +- deps/npm/html/doc/install.html | 2 +- deps/npm/html/doc/json.html | 2 +- deps/npm/html/doc/link.html | 2 +- deps/npm/html/doc/list.html | 2 +- deps/npm/html/doc/npm.html | 4 ++-- deps/npm/html/doc/outdated.html | 2 +- deps/npm/html/doc/owner.html | 2 +- deps/npm/html/doc/pack.html | 2 +- deps/npm/html/doc/prefix.html | 2 +- deps/npm/html/doc/prune.html | 2 +- deps/npm/html/doc/publish.html | 2 +- deps/npm/html/doc/rebuild.html | 2 +- deps/npm/html/doc/registry.html | 2 +- deps/npm/html/doc/removing-npm.html | 2 +- deps/npm/html/doc/restart.html | 2 +- deps/npm/html/doc/root.html | 2 +- deps/npm/html/doc/run-script.html | 2 +- deps/npm/html/doc/scripts.html | 2 +- deps/npm/html/doc/search.html | 2 +- deps/npm/html/doc/semver.html | 2 +- deps/npm/html/doc/star.html | 2 +- deps/npm/html/doc/start.html | 2 +- deps/npm/html/doc/stop.html | 2 +- deps/npm/html/doc/submodule.html | 2 +- deps/npm/html/doc/tag.html | 2 +- deps/npm/html/doc/test.html | 2 +- deps/npm/html/doc/uninstall.html | 2 +- deps/npm/html/doc/unpublish.html | 2 +- deps/npm/html/doc/update.html | 2 +- deps/npm/html/doc/version.html | 2 +- deps/npm/html/doc/view.html | 2 +- deps/npm/html/doc/whoami.html | 2 +- deps/npm/man/man1/npm.1 | 2 +- deps/npm/man/man3/npm.3 | 2 +- deps/npm/package.json | 2 +- 95 files changed, 97 insertions(+), 97 deletions(-) diff --git a/deps/npm/html/api/bin.html b/deps/npm/html/api/bin.html index c4392671df1..17c19b073ac 100644 --- a/deps/npm/html/api/bin.html +++ b/deps/npm/html/api/bin.html @@ -19,7 +19,7 @@

    This function should not be used programmatically. Instead, just refer to the npm.bin member.

    - + diff --git a/src/node_version.h b/src/node_version.h index c46c88b697e..d6f11afec26 100644 --- a/src/node_version.h +++ b/src/node_version.h @@ -29,7 +29,7 @@ #define NODE_MAJOR_VERSION 0 #define NODE_MINOR_VERSION 6 #define NODE_PATCH_VERSION 9 -#define NODE_VERSION_IS_RELEASE 0 +#define NODE_VERSION_IS_RELEASE 1 #ifndef NODE_STRINGIFY #define NODE_STRINGIFY(n) NODE_STRINGIFY_HELPER(n) From 5756d7916a1f6dfb9d0a7fc544b4a7fcc4e99a50 Mon Sep 17 00:00:00 2001 From: isaacs Date: Fri, 27 Jan 2012 16:54:40 -0800 Subject: [PATCH 28/36] Now working on 0.6.10 --- src/node_version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/node_version.h b/src/node_version.h index d6f11afec26..071fe984bcd 100644 --- a/src/node_version.h +++ b/src/node_version.h @@ -28,8 +28,8 @@ #define NODE_MAJOR_VERSION 0 #define NODE_MINOR_VERSION 6 -#define NODE_PATCH_VERSION 9 -#define NODE_VERSION_IS_RELEASE 1 +#define NODE_PATCH_VERSION 10 +#define NODE_VERSION_IS_RELEASE 0 #ifndef NODE_STRINGIFY #define NODE_STRINGIFY(n) NODE_STRINGIFY_HELPER(n) From ca4b91a1d00255da852ccfb856e2beda8a7030f7 Mon Sep 17 00:00:00 2001 From: isaacs Date: Fri, 27 Jan 2012 17:07:43 -0800 Subject: [PATCH 29/36] Correct spelling of Ben Noordhuis --- ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ede9435a6c2..5f3b69f5a8f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,6 @@ 2012.01.27, Version 0.6.9 (stable) -* dgram: Bring back missing functionality for Unix (Dan VerWeire, Roman Shtylman, Ben Noordnuis) +* dgram: Bring back missing functionality for Unix (Dan VerWeire, Roman Shtylman, Ben Noordhuis) - Note: Windows UDP support not yet complete. * http: Fix parser memory leak (koichik) From b221fe9b29f7dd834af9716e077bc05a05156d64 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Sun, 29 Jan 2012 23:30:13 +0100 Subject: [PATCH 30/36] timers: add v0.4 compatibility hack If a timer callback throws and the user's uncaughtException handler ignores the exception, other timers that expire on the current tick should still run. If #2582 goes through, this hack should be removed. Fixes #2631. --- lib/timers.js | 16 +++++- test/simple/test-timers-uncaught-exception.js | 52 +++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 test/simple/test-timers-uncaught-exception.js diff --git a/lib/timers.js b/lib/timers.js index 7a57d342776..c5592bf0a20 100644 --- a/lib/timers.js +++ b/lib/timers.js @@ -81,7 +81,21 @@ function insert(item, msecs) { } else { L.remove(first); assert(first !== L.peek(list)); - if (first._onTimeout) first._onTimeout(); + + if (!first._onTimeout) continue; + + // v0.4 compatibility: if the timer callback throws and the user's + // uncaughtException handler ignores the exception, other timers that + // expire on this tick should still run. If #2582 goes through, this + // hack should be removed. + // + // https://github.com/joyent/node/issues/2631 + try { + first._onTimeout(); + } catch (e) { + if (!process.listeners('uncaughtException').length) throw e; + process.emit('uncaughtException', e); + } } } diff --git a/test/simple/test-timers-uncaught-exception.js b/test/simple/test-timers-uncaught-exception.js new file mode 100644 index 00000000000..0d2f488df03 --- /dev/null +++ b/test/simple/test-timers-uncaught-exception.js @@ -0,0 +1,52 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var common = require('../common'); +var assert = require('assert'); + +var exceptions = 0; +var timer1 = 0; +var timer2 = 0; + +// the first timer throws... +setTimeout(function() { + timer1++; + throw new Error('BAM!'); +}, 100); + +// ...but the second one should still run +setTimeout(function() { + assert.equal(timer1, 1); + timer2++; +}, 100); + +function uncaughtException(err) { + assert.equal(err.message, 'BAM!'); + exceptions++; +} +process.on('uncaughtException', uncaughtException); + +process.on('exit', function() { + process.removeListener('uncaughtException', uncaughtException); + assert.equal(exceptions, 1); + assert.equal(timer1, 1); + assert.equal(timer2, 1); +}); From 3fd13c6426b338196d138b0dc564020daed78bcd Mon Sep 17 00:00:00 2001 From: koichik Date: Tue, 31 Jan 2012 00:16:01 +0900 Subject: [PATCH 31/36] http: fix free http-parser too early when the status code is 100 (Continue). Fixes #2636. --- lib/http.js | 6 +++++- test/simple/test-http-expect-continue.js | 4 +++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/http.js b/lib/http.js index a9aaac1c734..1d7eac32abf 100644 --- a/lib/http.js +++ b/lib/http.js @@ -1169,7 +1169,11 @@ ClientRequest.prototype.onSocket = function(socket) { socket.destroy(); } freeParser(); - } else if (parser.incoming && parser.incoming.complete) { + } else if (parser.incoming && parser.incoming.complete && + // When the status code is 100 (Continue), the server will + // send a final response after this client sends a request + // body. So, we must not free the parser. + parser.incoming.statusCode !== 100) { freeParser(); } }; diff --git a/test/simple/test-http-expect-continue.js b/test/simple/test-http-expect-continue.js index 3c3980a0ac9..54c04cce0ee 100644 --- a/test/simple/test-http-expect-continue.js +++ b/test/simple/test-http-expect-continue.js @@ -44,7 +44,9 @@ server.on('checkContinue', function(req, res) { common.debug('Server got Expect: 100-continue...'); res.writeContinue(); sent_continue = true; - handler(req, res); + setTimeout(function() { + handler(req, res); + }, 100); }); server.listen(common.PORT); From 0ad2a9a2e0c82f71efaa56cf4eb31c8912703065 Mon Sep 17 00:00:00 2001 From: Bert Belder Date: Tue, 31 Jan 2012 16:46:14 +0100 Subject: [PATCH 32/36] Small test-dgram-multicast-multi-process fixes Somehow windows doesn't want to bind to 224.0.0.1. Let's test with a multicast address that has no special meaning. --- test/simple/test-dgram-multicast-multi-process.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/simple/test-dgram-multicast-multi-process.js b/test/simple/test-dgram-multicast-multi-process.js index 03e07de57b8..35ade382e33 100644 --- a/test/simple/test-dgram-multicast-multi-process.js +++ b/test/simple/test-dgram-multicast-multi-process.js @@ -26,7 +26,7 @@ var common = require('../common'), assert = require('assert'), Buffer = require('buffer').Buffer, fork = require('child_process').fork, - LOCAL_BROADCAST_HOST = '224.0.0.1', + LOCAL_BROADCAST_HOST = '224.0.0.114', TIMEOUT = 5000, messages = [ new Buffer('First message to send'), @@ -153,8 +153,8 @@ if (process.argv[2] !== 'child') { sendSocket.send(buf, 0, buf.length, common.PORT, LOCAL_BROADCAST_HOST, function(err) { if (err) throw err; - console.error('sent %s to %s', util.inspect(buf.toString()), - LOCAL_BROADCAST_HOST + common.PORT); + console.error('sent %s to %s:%s', util.inspect(buf.toString()), + LOCAL_BROADCAST_HOST, common.PORT); process.nextTick(sendSocket.sendNext); }); }; From fa490f64971a38c98d74dc6b55b2d88dd1f6c463 Mon Sep 17 00:00:00 2001 From: Bert Belder Date: Tue, 31 Jan 2012 17:41:46 +0100 Subject: [PATCH 33/36] uv: upgrade to 3eb94e9 --- deps/uv/src/unix/pipe.c | 1 - deps/uv/src/unix/udp.c | 10 +- deps/uv/src/win/fs.c | 2 +- deps/uv/src/win/udp.c | 139 +++++++++++++++++++------ deps/uv/test/test-fs.c | 3 + deps/uv/test/test-list.h | 2 + deps/uv/test/test-udp-multicast-join.c | 2 +- deps/uv/test/test-udp-options.c | 85 +++++++++++++++ deps/uv/uv.gyp | 1 + deps/uv/vcbuild.bat | 14 ++- 10 files changed, 223 insertions(+), 36 deletions(-) create mode 100644 deps/uv/test/test-udp-options.c diff --git a/deps/uv/src/unix/pipe.c b/deps/uv/src/unix/pipe.c index 5509136a75c..f1be9e972bc 100644 --- a/deps/uv/src/unix/pipe.c +++ b/deps/uv/src/unix/pipe.c @@ -251,7 +251,6 @@ void uv__pipe_accept(EV_P_ ev_io* watcher, int revents) { pipe = watcher->data; assert(pipe->type == UV_NAMED_PIPE); - assert(pipe->pipe_fname != NULL); sockfd = uv__accept(pipe->fd, (struct sockaddr *)&saddr, sizeof saddr); if (sockfd == -1) { diff --git a/deps/uv/src/unix/udp.c b/deps/uv/src/unix/udp.c index 91f7d1a2fde..349bfae3cd6 100644 --- a/deps/uv/src/unix/udp.c +++ b/deps/uv/src/unix/udp.c @@ -340,7 +340,15 @@ static int uv__bind(uv_udp_t* handle, goto out; } -#ifdef SO_REUSEPORT /* Apple's version of SO_REUSEADDR... */ + /* On the BSDs, SO_REUSEADDR lets you reuse an address that's in the TIME_WAIT + * state (i.e. was until recently tied to a socket) while SO_REUSEPORT lets + * multiple processes bind to the same address. Yes, it's something of a + * misnomer but then again, SO_REUSEADDR was already taken. + * + * None of the above applies to Linux: SO_REUSEADDR implies SO_REUSEPORT on + * Linux and hence it does not have SO_REUSEPORT at all. + */ +#ifdef SO_REUSEPORT yes = 1; if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof yes) == -1) { uv__set_sys_error(handle->loop, errno); diff --git a/deps/uv/src/win/fs.c b/deps/uv/src/win/fs.c index 6948f7ef1cd..5248ac2a99e 100644 --- a/deps/uv/src/win/fs.c +++ b/deps/uv/src/win/fs.c @@ -541,7 +541,7 @@ static int uv__is_root(const wchar_t* path) { size_t len = wcslen(path); /* Test for \ */ - if (len == 0 && IS_SLASH(path[0])) { + if (len == 1 && IS_SLASH(path[0])) { return 1; } diff --git a/deps/uv/src/win/udp.c b/deps/uv/src/win/udp.c index 0a9990a5b75..39221de6f7d 100644 --- a/deps/uv/src/win/udp.c +++ b/deps/uv/src/win/udp.c @@ -166,9 +166,9 @@ static int uv__bind(uv_udp_t* handle, struct sockaddr* addr, int addrsize, unsigned int flags) { - DWORD err; int r; SOCKET sock; + DWORD no = 0, yes = 1; if ((flags & UV_UDP_IPV6ONLY) && domain != AF_INET6) { /* UV_UDP_IPV6ONLY is supported only for IPV6 sockets */ @@ -190,7 +190,6 @@ static int uv__bind(uv_udp_t* handle, } if (domain == AF_INET6 && !(flags & UV_UDP_IPV6ONLY)) { - DWORD off = 0; /* On windows IPV6ONLY is on by default. */ /* If the user doesn't specify it libuv turns it off. */ @@ -200,14 +199,22 @@ static int uv__bind(uv_udp_t* handle, setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, - (const char*) &off, - sizeof off); + (char*) &no, + sizeof no); + } + + r = setsockopt(sock, + SOL_SOCKET, + SO_REUSEADDR, + (char*) &yes, + sizeof yes); + if (r == SOCKET_ERROR) { + uv__set_sys_error(handle->loop, WSAGetLastError()); + return -1; } r = bind(handle->socket, addr, addrsize); - if (r == SOCKET_ERROR) { - err = WSAGetLastError(); uv__set_sys_error(handle->loop, WSAGetLastError()); return -1; } @@ -244,15 +251,6 @@ int uv__udp_bind6(uv_udp_t* handle, struct sockaddr_in6 addr, } -int uv_udp_set_membership(uv_udp_t* handle, const char* multicast_addr, - const char* interface_addr, uv_membership membership) { - - /* not implemented yet */ - uv__set_artificial_error(handle->loop, UV_ENOSYS); - return -1; -} - - static void uv_udp_queue_recv(uv_loop_t* loop, uv_udp_t* handle) { uv_req_t* req; uv_buf_t buf; @@ -579,16 +577,50 @@ void uv_process_udp_send_req(uv_loop_t* loop, uv_udp_t* handle, } -int uv_udp_set_multicast_loop(uv_udp_t* handle, int on) { - uv__set_artificial_error(handle->loop, UV_ENOSYS); - return -1; -} +int uv_udp_set_membership(uv_udp_t* handle, const char* multicast_addr, + const char* interface_addr, uv_membership membership) { + int optname; + struct ip_mreq mreq; + /* If the socket is unbound, bind to inaddr_any. */ + if (!(handle->flags & UV_HANDLE_BOUND) && + uv_udp_bind(handle, uv_addr_ip4_any_, 0) < 0) { + return -1; + } -int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl) { - if (setsockopt(handle->socket, IPPROTO_IP, IP_MULTICAST_TTL, - (const char*)&ttl, sizeof ttl) == -1) { - uv__set_sys_error(handle->loop, WSAGetLastError()); + if (handle->flags & UV_HANDLE_IPV6) { + uv__set_artificial_error(handle->loop, UV_ENOSYS); + return -1; + } + + memset(&mreq, 0, sizeof mreq); + + if (interface_addr) { + mreq.imr_interface.s_addr = inet_addr(interface_addr); + } else { + mreq.imr_interface.s_addr = htonl(INADDR_ANY); + } + + mreq.imr_multiaddr.s_addr = inet_addr(multicast_addr); + + switch (membership) { + case UV_JOIN_GROUP: + optname = IP_ADD_MEMBERSHIP; + break; + case UV_LEAVE_GROUP: + optname = IP_DROP_MEMBERSHIP; + break; + default: + uv__set_artificial_error(handle->loop, UV_EFAULT); + return -1; + } + + if (setsockopt(handle->socket, + IPPROTO_IP, + optname, + (char*) &mreq, + sizeof mreq) == SOCKET_ERROR) { + uv__set_sys_error(handle->loop, WSAGetLastError()); return -1; } @@ -596,18 +628,63 @@ int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl) { } -int uv_udp_set_broadcast(uv_udp_t* handle, int on) { - if (setsockopt(handle->socket, SOL_SOCKET, SO_BROADCAST, (const char*)&on, - sizeof on) == -1) { - uv__set_sys_error(handle->loop, WSAGetLastError()); +int uv_udp_set_broadcast(uv_udp_t* handle, int value) { + BOOL optval = (BOOL) value; + + /* If the socket is unbound, bind to inaddr_any. */ + if (!(handle->flags & UV_HANDLE_BOUND) && + uv_udp_bind(handle, uv_addr_ip4_any_, 0) < 0) { return -1; } + if (setsockopt(handle->socket, + SOL_SOCKET, + SO_BROADCAST, + (char*) &optval, + sizeof optval)) { + uv__set_sys_error(handle->loop, WSAGetLastError()); + return -1; + } return 0; } -int uv_udp_set_ttl(uv_udp_t* handle, int ttl) { - uv__set_artificial_error(handle->loop, UV_ENOSYS); - return -1; -} +#define SOCKOPT_SETTER(name, option4, option6) \ + int uv_udp_set_##name(uv_udp_t* handle, int value) { \ + DWORD optval = (DWORD) value; \ + \ + /* If the socket is unbound, bind to inaddr_any. */ \ + if (!(handle->flags & UV_HANDLE_BOUND) && \ + uv_udp_bind(handle, uv_addr_ip4_any_, 0) < 0) { \ + return -1; \ + } \ + \ + if (!(handle->flags & UV_HANDLE_IPV6)) { \ + /* Set IPv4 socket option */ \ + if (setsockopt(handle->socket, \ + IPPROTO_IP, \ + option4, \ + (char*) &optval, \ + sizeof optval)) { \ + uv__set_sys_error(handle->loop, WSAGetLastError()); \ + return -1; \ + } \ + } else { \ + /* Set IPv6 socket option */ \ + if (setsockopt(handle->socket, \ + IPPROTO_IPV6, \ + option6, \ + (char*) &optval, \ + sizeof optval)) { \ + uv__set_sys_error(handle->loop, WSAGetLastError()); \ + return -1; \ + } \ + } \ + return 0; \ + } + +SOCKOPT_SETTER(multicast_loop, IP_MULTICAST_LOOP, IPV6_MULTICAST_LOOP) +SOCKOPT_SETTER(multicast_ttl, IP_MULTICAST_TTL, IPV6_MULTICAST_HOPS) +SOCKOPT_SETTER(ttl, IP_TTL, IPV6_HOPLIMIT) + +#undef SOCKOPT_SETTER diff --git a/deps/uv/test/test-fs.c b/deps/uv/test/test-fs.c index 1601ac442fd..b88636b01df 100644 --- a/deps/uv/test/test-fs.c +++ b/deps/uv/test/test-fs.c @@ -1293,6 +1293,9 @@ TEST_IMPL(fs_stat_root) { int r; uv_loop_t* loop = uv_default_loop(); + r = uv_fs_stat(loop, &stat_req, "\\", NULL); + ASSERT(r == 0); + r = uv_fs_stat(loop, &stat_req, "c:\\", NULL); ASSERT(r == 0); diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h index acc5cea938f..02fabcb9ed5 100644 --- a/deps/uv/test/test-list.h +++ b/deps/uv/test/test-list.h @@ -50,6 +50,7 @@ TEST_DECLARE (udp_multicast_join) TEST_DECLARE (udp_dgram_too_big) TEST_DECLARE (udp_dual_stack) TEST_DECLARE (udp_ipv6_only) +TEST_DECLARE (udp_options) TEST_DECLARE (pipe_bind_error_addrinuse) TEST_DECLARE (pipe_bind_error_addrnotavail) TEST_DECLARE (pipe_bind_error_inval) @@ -187,6 +188,7 @@ TASK_LIST_START TEST_ENTRY (udp_dgram_too_big) TEST_ENTRY (udp_dual_stack) TEST_ENTRY (udp_ipv6_only) + TEST_ENTRY (udp_options) TEST_ENTRY (udp_multicast_join) TEST_ENTRY (pipe_bind_error_addrinuse) diff --git a/deps/uv/test/test-udp-multicast-join.c b/deps/uv/test/test-udp-multicast-join.c index 159dba08196..b32ef0737ae 100644 --- a/deps/uv/test/test-udp-multicast-join.c +++ b/deps/uv/test/test-udp-multicast-join.c @@ -99,7 +99,7 @@ TEST_IMPL(udp_multicast_join) { int r; uv_udp_send_t req; uv_buf_t buf; - struct sockaddr_in addr = uv_ip4_addr("239.255.0.1", TEST_PORT); + struct sockaddr_in addr = uv_ip4_addr("127.0.0.1", TEST_PORT); r = uv_udp_init(uv_default_loop(), &server); ASSERT(r == 0); diff --git a/deps/uv/test/test-udp-options.c b/deps/uv/test/test-udp-options.c new file mode 100644 index 00000000000..b47457417e8 --- /dev/null +++ b/deps/uv/test/test-udp-options.c @@ -0,0 +1,85 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include +#include + + +TEST_IMPL(udp_options) { + uv_loop_t* loop; + uv_udp_t h; + int i, r; + + loop = uv_default_loop(); + + r = uv_udp_init(loop, &h); + ASSERT(r == 0); + + uv_unref(loop); /* don't keep the loop alive */ + + r = uv_udp_bind(&h, uv_ip4_addr("0.0.0.0", TEST_PORT), 0); + ASSERT(r == 0); + + r = uv_udp_set_broadcast(&h, 1); + r |= uv_udp_set_broadcast(&h, 1); + r |= uv_udp_set_broadcast(&h, 0); + r |= uv_udp_set_broadcast(&h, 0); + ASSERT(r == 0); + + /* values 0-255 should work */ + for (i = 0; i <= 255; i++) { + r = uv_udp_set_ttl(&h, i); + ASSERT(r == 0); + } + + /* anything >255 should fail */ + r = uv_udp_set_ttl(&h, 256); + ASSERT(r == -1); + ASSERT(uv_last_error(loop).code == UV_EINVAL); + /* don't test ttl=-1, it's a valid value on some platforms */ + + r = uv_udp_set_multicast_loop(&h, 1); + r |= uv_udp_set_multicast_loop(&h, 1); + r |= uv_udp_set_multicast_loop(&h, 0); + r |= uv_udp_set_multicast_loop(&h, 0); + ASSERT(r == 0); + + /* values 0-255 should work */ + for (i = 0; i <= 255; i++) { + r = uv_udp_set_multicast_ttl(&h, i); + ASSERT(r == 0); + } + + /* anything >255 should fail */ + r = uv_udp_set_multicast_ttl(&h, 256); + ASSERT(r == -1); + ASSERT(uv_last_error(loop).code == UV_EINVAL); + /* don't test ttl=-1, it's a valid value on some platforms */ + + r = uv_run(loop); + ASSERT(r == 0); + + return 0; +} diff --git a/deps/uv/uv.gyp b/deps/uv/uv.gyp index dc0c0f3ac9e..1bc9ff9b4d6 100644 --- a/deps/uv/uv.gyp +++ b/deps/uv/uv.gyp @@ -317,6 +317,7 @@ 'test/test-tty.c', 'test/test-udp-dgram-too-big.c', 'test/test-udp-ipv6.c', + 'test/test-udp-options.c', 'test/test-udp-send-and-recv.c', 'test/test-udp-multicast-join.c', 'test/test-counters-init.c', diff --git a/deps/uv/vcbuild.bat b/deps/uv/vcbuild.bat index bccefff9dcd..644f574c22b 100644 --- a/deps/uv/vcbuild.bat +++ b/deps/uv/vcbuild.bat @@ -64,9 +64,21 @@ echo Project files generated. @rem Skip project generation if requested. if defined nobuild goto run -if not defined VCINSTALLDIR echo Build skipped. To build, this file needs to run from VS cmd prompt.& goto run +@rem If not running in the VS build env, try to start it. If that fails, bail +@rem out. +if defined VCINSTALLDIR goto msbuild-found +if not defined VS100COMNTOOLS goto msbuild-not-found +if not exist "%VS100COMNTOOLS%\..\..\vc\vcvarsall.bat" goto msbuild-not-found +call "%VS100COMNTOOLS%\..\..\vc\vcvarsall.bat" +if not defined VCINSTALLDIR goto msbuild-not-found +goto msbuild-found + +:msbuild-not-found +echo Build skipped. To build, this file needs to run from VS cmd prompt. +goto run @rem Build the sln with msbuild. +:msbuild-found msbuild uv.sln /t:%target% /p:Configuration=%config% /clp:NoSummary;NoItemAndPropertyList;Verbosity=minimal /nologo if errorlevel 1 goto exit From 35b3d151949e023eee07c118bf89826519fee488 Mon Sep 17 00:00:00 2001 From: Dan VerWeire Date: Mon, 30 Jan 2012 10:04:20 -0500 Subject: [PATCH 34/36] test: dgram-{broadcast,multicast}-multi-process : prevent false failures * check exit code of child processes * wait 1000 ms to exit the child process * prefix log messages with [PARENT] or [CHILD] to help debugging * kill all child processes before exiting Conflicts: test/simple/test-dgram-multicast-multi-process.js --- .../test-dgram-broadcast-multi-process.js | 50 +++++++++++++------ .../test-dgram-multicast-multi-process.js | 50 +++++++++++++------ 2 files changed, 71 insertions(+), 29 deletions(-) diff --git a/test/simple/test-dgram-broadcast-multi-process.js b/test/simple/test-dgram-broadcast-multi-process.js index 3c042243850..7ef40705814 100644 --- a/test/simple/test-dgram-broadcast-multi-process.js +++ b/test/simple/test-dgram-broadcast-multi-process.js @@ -46,8 +46,11 @@ if (process.argv[2] !== 'child') { //exit the test if it doesn't succeed within TIMEOUT timer = setTimeout(function () { - console.error('Responses were not received within %d ms.', TIMEOUT); - console.error('Fail'); + console.error('[PARENT] Responses were not received within %d ms.', TIMEOUT); + console.error('[PARENT] Fail'); + + killChildren(workers); + process.exit(1); }, TIMEOUT); @@ -62,16 +65,20 @@ if (process.argv[2] !== 'child') { //handle the death of workers worker.on('exit', function (code, signal) { //don't consider this the true death if the worker has finished successfully - if (worker.isDone) { + //or if the exit code is 0 + if (worker.isDone || code == 0) { return; } dead += 1; - console.error('Worker %d died. %d dead of %d', worker.pid, dead, listeners); + console.error('[PARENT] Worker %d died. %d dead of %d', worker.pid, dead, listeners); if (dead === listeners) { - console.error('All workers have died.'); - console.error('Fail'); + console.error('[PARENT] All workers have died.'); + console.error('[PARENT] Fail'); + + killChildren(workers); + process.exit(1); } }); @@ -91,12 +98,12 @@ if (process.argv[2] !== 'child') { if (worker.messagesReceived.length === messages.length) { done += 1; worker.isDone = true; - console.error('%d received %d messages total.', worker.pid, + console.error('[PARENT] %d received %d messages total.', worker.pid, worker.messagesReceived.length); } if (done === listeners) { - console.error('All workers have received the required number of ' + console.error('[PARENT] All workers have received the required number of ' + 'messages. Will now compare.'); Object.keys(workers).forEach(function (pid) { @@ -113,7 +120,7 @@ if (process.argv[2] !== 'child') { } }); - console.error('%d received %d matching messges.', worker.pid + console.error('[PARENT] %d received %d matching messges.', worker.pid , count); assert.equal(count, messages.length @@ -121,7 +128,8 @@ if (process.argv[2] !== 'child') { }); clearTimeout(timer); - console.error('Success'); + console.error('[PARENT] Success'); + killChildren(workers); } } }); @@ -134,7 +142,7 @@ if (process.argv[2] !== 'child') { sendSocket.setBroadcast(true); sendSocket.on('close', function() { - console.error('sendSocket closed'); + console.error('[PARENT] sendSocket closed'); }); sendSocket.sendNext = function() { @@ -150,12 +158,19 @@ if (process.argv[2] !== 'child') { if (err) throw err; - console.error('sent %s to %s:%s', util.inspect(buf.toString()) + console.error('[PARENT] sent %s to %s:%s', util.inspect(buf.toString()) , LOCAL_BROADCAST_HOST, common.PORT); process.nextTick(sendSocket.sendNext); }); }; + + function killChildren(children) { + Object.keys(children).forEach(function(key) { + var child = children[key]; + child.kill(); + }); + } } if (process.argv[2] === 'child') { @@ -163,7 +178,7 @@ if (process.argv[2] === 'child') { var listenSocket = dgram.createSocket('udp4'); listenSocket.on('message', function(buf, rinfo) { - console.error('%s received %s from %j', process.pid + console.error('[CHILD] %s received %s from %j', process.pid , util.inspect(buf.toString()), rinfo); receivedMessages.push(buf); @@ -171,14 +186,19 @@ if (process.argv[2] === 'child') { process.send({ message : buf.toString() }); if (receivedMessages.length == messages.length) { - process.nextTick(function() { + process.nextTick(function () { listenSocket.close(); }); } }); listenSocket.on('close', function() { - process.exit(); + //HACK: Wait to exit the process to ensure that the parent + //process has had time to receive all messages via process.send() + //This may be indicitave of some other issue. + setTimeout(function() { + process.exit(); + }, 1000); }); listenSocket.on('listening', function() { diff --git a/test/simple/test-dgram-multicast-multi-process.js b/test/simple/test-dgram-multicast-multi-process.js index 35ade382e33..d6f1c4793d2 100644 --- a/test/simple/test-dgram-multicast-multi-process.js +++ b/test/simple/test-dgram-multicast-multi-process.js @@ -46,8 +46,11 @@ if (process.argv[2] !== 'child') { //exit the test if it doesn't succeed within TIMEOUT timer = setTimeout(function () { - console.error('Responses were not received within %d ms.', TIMEOUT); - console.error('Fail'); + console.error('[PARENT] Responses were not received within %d ms.', TIMEOUT); + console.error('[PARENT] Fail'); + + killChildren(workers); + process.exit(1); }, TIMEOUT); @@ -62,16 +65,21 @@ if (process.argv[2] !== 'child') { //handle the death of workers worker.on('exit', function (code, signal) { //don't consider this the true death if the worker has finished successfully - if (worker.isDone) { + + //or if the exit code is 0 + if (worker.isDone || code === 0) { return; } dead += 1; - console.error('Worker %d died. %d dead of %d', worker.pid, dead, listeners); + console.error('[PARENT] Worker %d died. %d dead of %d', worker.pid, dead, listeners); if (dead === listeners) { - console.error('All workers have died.'); - console.error('Fail'); + console.error('[PARENT] All workers have died.'); + console.error('[PARENT] Fail'); + + killChildren(workers); + process.exit(1); } }); @@ -91,12 +99,12 @@ if (process.argv[2] !== 'child') { if (worker.messagesReceived.length === messages.length) { done += 1; worker.isDone = true; - console.error('%d received %d messages total.', worker.pid, + console.error('[PARENT] %d received %d messages total.', worker.pid, worker.messagesReceived.length); } if (done === listeners) { - console.error('All workers have received the required number of ' + console.error('[PARENT] All workers have received the required number of ' + 'messages. Will now compare.'); Object.keys(workers).forEach(function (pid) { @@ -113,7 +121,7 @@ if (process.argv[2] !== 'child') { } }); - console.error('%d received %d matching messages.', worker.pid + console.error('[PARENT] %d received %d matching messages.', worker.pid , count); assert.equal(count, messages.length @@ -121,7 +129,8 @@ if (process.argv[2] !== 'child') { }); clearTimeout(timer); - console.error('Success'); + console.error('[PARENT] Success'); + killChildren(workers); } } }); @@ -139,7 +148,7 @@ if (process.argv[2] !== 'child') { sendSocket.setMulticastLoopback(true); sendSocket.on('close', function() { - console.error('sendSocket closed'); + console.error('[PARENT] sendSocket closed'); }); sendSocket.sendNext = function() { @@ -153,11 +162,18 @@ if (process.argv[2] !== 'child') { sendSocket.send(buf, 0, buf.length, common.PORT, LOCAL_BROADCAST_HOST, function(err) { if (err) throw err; - console.error('sent %s to %s:%s', util.inspect(buf.toString()), + console.error('[PARENT] sent %s to %s:%s', util.inspect(buf.toString()), LOCAL_BROADCAST_HOST, common.PORT); process.nextTick(sendSocket.sendNext); }); }; + + function killChildren(children) { + Object.keys(children).forEach(function(key) { + var child = children[key]; + child.kill(); + }); + } } if (process.argv[2] === 'child') { @@ -165,7 +181,7 @@ if (process.argv[2] === 'child') { var listenSocket = dgram.createSocket('udp4'); listenSocket.on('message', function(buf, rinfo) { - console.error('%s received %s from %j', process.pid + console.error('[CHILD] %s received %s from %j', process.pid ,util.inspect(buf.toString()), rinfo); receivedMessages.push(buf); @@ -174,6 +190,7 @@ if (process.argv[2] === 'child') { if (receivedMessages.length == messages.length) { listenSocket.dropMembership(LOCAL_BROADCAST_HOST); + process.nextTick(function() { // TODO should be changed to below. // listenSocket.dropMembership(LOCAL_BROADCAST_HOST, function() { listenSocket.close(); @@ -182,7 +199,12 @@ if (process.argv[2] === 'child') { }); listenSocket.on('close', function() { - process.exit(); + //HACK: Wait to exit the process to ensure that the parent + //process has had time to receive all messages via process.send() + //This may be indicitave of some other issue. + setTimeout(function () { + process.exit(); + }, 1000); }); listenSocket.on('listening', function() { From 840229a8251955d2b791928875f36d35127dcad0 Mon Sep 17 00:00:00 2001 From: Paddy Byers Date: Tue, 22 Nov 2011 23:46:01 +0000 Subject: [PATCH 35/36] Tidy _resolveFilename --- lib/module.js | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/lib/module.js b/lib/module.js index da67ef65d26..bbb1556bb82 100644 --- a/lib/module.js +++ b/lib/module.js @@ -276,18 +276,16 @@ Module._load = function(request, parent, isMain) { debug('Module._load REQUEST ' + (request) + ' parent: ' + parent.id); } - var resolved = Module._resolveFilename(request, parent); - var id = resolved[0]; - var filename = resolved[1]; + var filename = Module._resolveFilename(request, parent); var cachedModule = Module._cache[filename]; if (cachedModule) { return cachedModule.exports; } - if (NativeModule.exists(id)) { + if (NativeModule.exists(filename)) { // REPL is a special case, because it needs the real require. - if (id == 'repl') { + if (filename == 'repl') { var replModule = new Module('repl'); replModule._compile(NativeModule.getSource('repl'), 'repl.js'); NativeModule._cache.repl = replModule; @@ -295,10 +293,10 @@ Module._load = function(request, parent, isMain) { } debug('load native module ' + request); - return NativeModule.require(id); + return NativeModule.require(filename); } - var module = new Module(id, parent); + var module = new Module(filename, parent); if (isMain) { process.mainModule = module; @@ -318,7 +316,7 @@ Module._load = function(request, parent, isMain) { Module._resolveFilename = function(request, parent) { if (NativeModule.exists(request)) { - return [request, request]; + return request; } var resolvedModule = Module._resolveLookupPaths(request, parent); @@ -333,8 +331,7 @@ Module._resolveFilename = function(request, parent) { if (!filename) { throw new Error("Cannot find module '" + request + "'"); } - id = filename; - return [id, filename]; + return filename; }; @@ -374,7 +371,7 @@ Module.prototype._compile = function(content, filename) { } require.resolve = function(request) { - return Module._resolveFilename(request, self)[1]; + return Module._resolveFilename(request, self); }; Object.defineProperty(require, 'paths', { get: function() { From 7e0bf7d57de318f45a097e05644efa49beb65209 Mon Sep 17 00:00:00 2001 From: Paddy Byers Date: Tue, 22 Nov 2011 23:49:18 +0000 Subject: [PATCH 36/36] Process symlinked shared library as .node --- lib/module.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/module.js b/lib/module.js index bbb1556bb82..893de411391 100644 --- a/lib/module.js +++ b/lib/module.js @@ -467,11 +467,11 @@ Module._extensions['.json'] = function(module, filename) { }; -//Native extension for .node +//Native extension for .node and OS-specific equivalents Module._extensions['.node'] = function(module, filename) { process.dlopen(filename, module.exports); }; - +Module._extensions['.dylib'] = Module._extensions['.node']; // bootstrap main module. Module.runMain = function() {